我的查询运行得非常快(1秒),见下文:
SELECT *
FROM ( select ROW_NUMBER() OVER ( ORDER BY [Rank] DESC ) AS RowNum, *
FROM [product].[FnSearchKeyword]('basic', null, null, null, null, null, null, null)
) AS RowConstrainedResult
WHERE RowNum = 1 AND RowNum < 30
如果我将此查询放在一个程序中,则运行时需要15秒才能运行,如下所示:
CREATE anydata
@keywords nvarchar(4000),
@minimunRate int,
@priceFrom decimal,
@priceTo decimal,
@relaeseStart datetime,
@releaseEnd datetime,
@categoryList nvarchar(4000),
@storeList nvarchar(4000),
@rowBegin int,
@rowEnd int,
@orderBy int,
@isAdult bit = null
AS
SELECT *
FROM ( select ROW_NUMBER() OVER ( ORDER BY [Rank] DESC ) AS RowNum, *
FROM [product].[FnSearchKeyword]('basic', @minimunRate , @priceFrom , @priceTo , null, null, null, null)
) AS RowConstrainedResult
WHERE RowNum = 1 AND RowNum < 30
当我播放SQL时,返回延迟为15秒:
exec anydata null, null, null, null, null, null, null, null, null, null, null
注意:
函数FnSearchKeyword的参数在AnyData Procedure中具有相同的声明类型。
我在exec过程中传递所有值“NULL”,只是为了得到与上面显示的运行速度快的查询相同的结果。参数范围没有变化
老实说,我注意到当我通过Procedure运行查询时,“执行计划”被更改,但由于查询的参数相同,所以不知道如何解决这个问题。
不幸的是,由于此处未提及的其他原因,我需要将其置于PROC查询中,以免使问题进一步复杂化。
关于重复消息:它的问题没有重复,因为它在任何系统中运行缓慢(查询分析器,C#asp.net,其他)。
答案 0 :(得分:4)
存储过程现在的参数是相同的,但是计划首次缓存时它们是什么?您可以通过添加OPTION RECOMPILE
来阻止参数嗅探。
如果是2008+(请指定版本!),由于语句本身应使用相同的计划,因此您还应检查会话和存储过程的SET设置。例如,让ARITHABORT
为一个而不是另一个可以导致不同的计划,如果你有不同的计划,一个可能是坏的,一个可能是好的。另请注意,即使查询文本中的单个空格差异也可以使SQL Server将它们视为两个不同的计划。
通过强制设置和查询文本相同,您可以避免这些计划差异,但仍然无法通过这种方式控制参数嗅探问题。如果是参数嗅探问题,您还可以试用OPTIMIZE FOR
...