1

我有一个运行速度非常快(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 过程中具有相同的声明类型。

  • 我在 exec 过程中传递了所有值“NULL”,只是为了得到与上面快速运行的查询相同的结果。参数范围没有变化

老实说,当我通过程序运行查询时,我注意到“执行计划”发生了变化,但不知道如何解决这个问题,因为查询的参数是相同的。

不幸的是,由于此处未提及的其他原因,我需要将其放入 PROC 查询中,以免使问题进一步复杂化。

关于重复消息:它的问题没有重复,因为它在任何系统(查询分析器、C# asp.net 等)中运行缓慢。

4

1 回答 1

4

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

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

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

于 2013-02-21T18:19:41.887 回答