使用相同的参数,相同的SQL运行速度更慢或更快

时间:2013-02-21 18:12:39

标签: sql sql-server performance stored-procedures sql-execution-plan

我的查询运行得非常快(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,其他)。

1 个答案:

答案 0 :(得分:4)

存储过程现在的参数是相同的,但是计划首次缓存时它们是什么?您可以通过添加OPTION RECOMPILE来阻止参数嗅探。

如果是2008+(请指定版本!),由于语句本身应使用相同的计划,因此您还应检查会话和存储过程的SET设置。例如,让ARITHABORT为一个而不是另一个可以导致不同的计划,如果你有不同的计划,一个可能是坏的,一个可能是好的。另请注意,即使查询文本中的单个空格差异也可以使SQL Server将它们视为两个不同的计划。

通过强制设置和查询文本相同,您可以避免这些计划差异,但仍然无法通过这种方式控制参数嗅探问题。如果是参数嗅探问题,您还可以试用OPTIMIZE FOR ...