Asp.net 当我传递@ip=''时,存储过程在if语句中花费了太多的时间,并花费了0秒的时间将某些值传递给@ip
我已经低于SP,它花费了太多的时间,最后停止与Asp.net 当我传递@ip=''时,存储过程在if语句中花费了太多的时间,并花费了0秒的时间将某些值传递给@ip,asp.net,sql-server,stored-procedures,Asp.net,Sql Server,Stored Procedures,我已经低于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), @sortColu
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
根据错误消息更新: 您需要检查select查询的数据长度,并确保@Temp表列定义正确。例如您可以将Country varchar25的列长度扩展到Country varchar50 另外,我认为你的陈述毫无意义。您的案例有效地做到了以下几点:
row_number() over (order by 0)
此外,您还可以使用标识1,1列ie声明@Temp表,如下所示;identityseed,递增以获取行号,而不使用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
正如我在评论中所写,你的第一个问题的答案是:
如果我很了解您的PRC,在@IP=的情况下,它应该返回一组wieder成员。我认为可能是用户名、电子邮件或国家/地区在成员表中比@Temp表的定义更长。将@Temp的列长度与表成员匹配 你问题的第二个答案: 如果@IP='some value',则需要0秒,如果@IP=,则需要0秒 1:50分钟,这里怎么了 我认为你应该把你的prc分成两部分。使用@IP=和@somevalue运行这两个查询,并检查执行计划 如果您看到,它与“somevalue”配合良好,并且不需要索引,那么我认为您的查询是的牺牲品,这通常意味着您的执行计划经过优化以检索所有可能的内容,而进行更具选择性的搜索则不是最佳的
可能它是针对我链接的文章中描述的完整表扫描进行了优化。如果我很了解您的PRC,在@IP=的情况下,它应该返回一组wieder成员。我认为可能是用户名、电子邮件或国家/地区在成员表中比@Temp表的定义更长。匹配@Temp wit table member的列长度。如果是这种情况,那么它也不应该与@IP='::1'等一起工作。@AndrásOttó:更正列长度后,我能够得到结果,但执行结果需要1:45分钟,这是最差的。@AndrásOttó:如果@IP='some value',则需要0秒,如果@IP=,需要1:50分钟。这里出了什么问题。可能在l.address=@IP上的搜索更改了quryplan并需要额外的时间。分别检查IF…ELSE两侧的queryplan,您将看到区别,并且可能调优顾问将为您提供一个Indexcase语句是否正确及其分页存储过程,因此我不能保留row_number函数。是的,它们是,但它们有意义吗?这里:当@sortOrder'asc'时为0,当@sortColumn='id'时为0,则id结束asc时,它将永远不会计算@sortColumn='id'。我想你在这儿等着呢。但简化版本在没有row_numberWhat(如果我传递@sortColumn='id')的情况下也会这样做:而且,在自定义分页的情况下,row_numbers函数必须根据排序列进行排序,这样才有意义。问题不在这里,我不能在分页存储过程中保留case语句。这不是语法错误。但你的案例陈述不会产生你预期的结果。实际上,您所做的是将订单上的行数乘以0。我想我不能再解释你了…你能告诉我如何解决这个问题吗,因为我这里没有DBA。请阅读这篇关于参数嗅探文本的文章链接,这里有一些如何处理的建议。我认为行动计划第1节和第2节适合你的情况。
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))
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