-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可能比表的定义更长。匹配wit 表成员的列长度。Country@Temp@Temp

您的问题的第二个答案:

如果@IP='some value',则需要 0 秒,如果@IP='',则需要 1:50 分钟。这里有什么问题?

我认为你应该把你的 prc 分成两部分。运行两个查询(@IP = '' 和 = 'somevalue')并检查执行计划。

如果您看到它与 'somevalue' 配合良好并且不需要 an INDEX,我认为您的查询是参数嗅探的受害者,这通常意味着您的执行计划经过优化以检索所有可能性,而不是进行更具选择性的搜索的最佳选择。

full table scan正如我链接的文章中描述的那样,它可能已针对 a 进行了优化。

于 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 回答