-5

私はSPを下回っていて、時間がかかりすぎて、ついに停止しました

EXEC MemberListing 1,20,'','','RegDate','Desc',0

パラメータに値を渡すと機能し@IPます。理由はわかりません。

Create PROCEDURE MemberListing
    @PageNum as Int,
    @PerPageResult as Int,
    @Username as nvarchar(50),
    @IP as varchar(50),
    @sortColumn as Varchar(50),
    @sortOrder as Varchar(4),
    @TotalCount as int OUTPUT
AS
BEGIN   
    declare @Temp Table(RowNum int, id bigint, Username nvarchar(50), Email nvarchar(50), RegDate DateTime, Country varchar(25),
                            LastLogin DateTime, IsGoldMember varchar(1))
    declare @sort varchar(50)
    if @IP = ''
        BEGIN
            print 'if'
            SET FMTONLY OFF;
            Insert into @Temp
            Select ROW_NUMBER() over (order by  
            case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'id' then id end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Username' then Username end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Email' then Email end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Country' then Country end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end ASC

        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'id' then id end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Username' then Username end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Email' then Email end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Country' then Country end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end DESC
            ) As RowNum, * From (   
            SELECT 
                m.id,m.login as Username,m.email as Email,m.registrationdate as RegDate,c.name as Country,m.lastlogindate as LastLogin,
                CASE WHEN (r.description='goldmember' or r.description='goldmember_forever') then 1 end As IsGoldMember 
            from member m 
            join country c on m.country_id = c.id
            join user_role ur on m.id=ur.member_id
            join role r on r.id=ur.role_id
            left join lastip l on m.id=l.user_id
            where r.description <> 'administrator' and m.login like @Username+'%'
            ) as aab
            Select * from @Temp Where RowNum> @PageNum-1 and RowNum<@PerPageResult+@PageNum
            order by 
            case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'id' then id end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Username' then Username end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Email' then Email end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Country' then Country end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end ASC

        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'id' then id end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Username' then Username end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Email' then Email end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Country' then Country end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end DESC
        END
    ELSE
        BEGIN
            print 'else'
            SET FMTONLY OFF;
            Insert into @Temp
            Select ROW_NUMBER() over (order by  
            case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'id' then id end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Username' then Username end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Email' then Email end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Country' then Country end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end ASC

        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'id' then id end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Username' then Username end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Email' then Email end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Country' then Country end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end DESC
            ) As RowNum, * From (   
            SELECT 
                m.id,m.login as Username,m.email as Email,m.registrationdate as RegDate,c.name as Country,m.lastlogindate as LastLogin,
                CASE WHEN (r.description='goldmember' or r.description='goldmember_forever') then 1 end As IsGoldMember 
            from member m 
            join country c on m.country_id = c.id
            join user_role ur on m.id=ur.member_id
            join role r on r.id=ur.role_id
            left join lastip l on m.id=l.user_id
            where r.description <> 'administrator' and m.login like @Username+'%' and l.address = @IP
            ) as aa
            Select * from @Temp Where RowNum> @PageNum-1 and RowNum<@PerPageResult+@PageNum
            order by 
            case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'id' then id end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Username' then Username end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Email' then Email end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'Country' then Country end ASC
        ,   case when @sortOrder <> 'ASC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end ASC
        ,   case when @sortOrder <> 'ASC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end ASC

        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'id' then id end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Username' then Username end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Email' then Email end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'RegDate' then RegDate end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'Country' then Country end DESC
        ,   case when @sortOrder <> 'DESC' then cast(null as datetime) when @sortColumn = 'LastLogin' then LastLogin end DESC
        ,   case when @sortOrder <> 'DESC' then 0 when @sortColumn = 'IsGoldMember' then IsGoldMember end DESC
        END 
END

@IPパラメータに''を渡すと、以下のエラーが発生します。

if
Msg 8152, Level 16, State 2, Procedure MemberListing, Line 24
String or binary data would be truncated.
The statement has been terminated.

(0 row(s) affected)
4

2 に答える 2

2

コメントに書いたように、最初の質問の答えは次のとおりです。

私があなたの中国をよく理解していれば、より@IP = ''広いメンバーのセットが返されるはずです。Username, Emailorがテーブルの定義Countryよりもメンバーテーブルの方が長い可能性があると思います。ウィット テーブル メンバー@Tempの列の長さに合わせます。@Temp

あなたの質問に対する2番目の答え:

@IP='some value' の場合は 0 秒かかり、@IP='' の場合は 1:50 分かかります。ここで何が問題なのですか?

prc を 2 つの部分に分割する必要があると思います。両方のクエリ (@IP = '' と = 'somevalue' を使用) を実行し、実行計画を確認します。

'somevalue' でうまく機能INDEX、.より選択的な検索を行うのに最適です。

full table scanリンクした記事に記載されているように、おそらく最適化されていたのでしょう。

于 2013-03-04T10:15:13.703 に答える
0

エラーメッセージの更新に従って:

選択クエリのデータ長を確認し、@Temp テーブルの列が正しく定義されていることを確認する必要があります。例えば; の列の長さをに拡張できCountry varchar(25)ますCountry varchar(50)

CASEまた、あなたの発言は的外れだと思います。あなたCASEが効果的に行っていることは次のとおりです。

row_number() over (order by 0)

また、関数を使用せずに行番号を取得するために、列(つまり; )を使用@Tempして以下のようにテーブルを宣言することもできますidentity(1,1)identity(seed,increment)row_number()

declare @Temp Table(RowNum int identity(1,1), id bigint, Username nvarchar(50), 
                    Email nvarchar(50), RegDate DateTime, Country varchar(25),
                    LastLogin DateTime, IsGoldMember varchar(1))

これで関数を削除できますrow_number()ifそして、以下のように(条件のために)挿入を簡素化します

if (@IP = '')
begin
    insert into @Temp
    select m.id,m.login as Username,m.email as Email,m.registrationdate as RegDate,
           c.name as Country,m.lastlogindate as LastLogin,
           CASE when (r.description='goldmember' or r.description='goldmember_forever') 
                 then 1 end As IsGoldMember 
    from member m join country c on m.country_id = c.id
         join user_role ur on m.id=ur.member_id
         join role r on r.id=ur.role_id
         left join lastip l on m.id=l.user_id
    where r.description <> 'administrator' and m.login like @Username+'%'
    order by 
         case when @sortOrder = 'asc' and @sortColumn = 'id' then id  
              when @sortOrder = 'asc' and @sortColumn = 'Username' then Username  
              when @sortOrder = 'asc' and @sortColumn = 'Email' then Email
              ...
              when @sortColumn = 'id' then id desc
              when @sortColumn = 'Username' then Username desc
              when @sortColumn = 'Email' then Email decs
              ...
         end
     --Now your select query to select required row numbers
     --Note the change to your where clase to bring correct results.
     Select * from @Temp 
     Where RowNum > @PerPageResult*(@PageNum-1) and RowNum <= @PerPageResult*@PageNum
end else
begin
    --you could follow the same step here.
end
于 2013-03-04T09:29:08.240 に答える