相同的查询在SP中具有不同的执行计划

时间:2015-01-24 17:46:25

标签: sql asp.net .net sql-server performance

当在存储过程中放置​​完全相同的查询时,它会生成一个完全不同的执行计划,需要大约18秒。

当我单独运行时(并且只是在查询上面的DECLARE变量)它运行得快得多~1-2秒。

我可以做什么,以便SP中的查询在单独运行时使用执行计划运行?仅供参考,我甚至通过创建一个全新的存储过程并将查询复制粘贴到其中来重现该问题。结果相同~18秒。

查询如下所示,以供参考

select
    COUNT(b.BookKey) as RowCounter
from
    Books b (nolock) 
    inner join BookPublishRegions bp (nolock)
      on b.BookKey = bp.BookKey               
where           
    b.IsUnavailable = 0 and 
    (@AuthorKey is null or b.AuthorKey = @AuthorKey) and
    (b.Price between @MinPrice and @MaxPrice) and
    contains(bp.PublishRegionName, @SearchTerm)

我在b.IsUnavailable上有索引,b.AuthorKey,b.Price和bp.PublishRegionName上的全文索引。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

即使查询看起来相同,本地变量和参数也完全不同。对于局部变量,SQL Server根据统计平均密度值估计行计数,因为实际值在编译时是未知的。但是,在参数的情况下,实际参数值是"嗅探"并且从统计直方图中收集的估计数为所提供的实际值。如果估计的行数显着不同,则生成的执行计划可能会有所不同。

您提到的症状可能表明统计数据陈旧或提到的参数嗅探问题。尝试使用FULLSCAN更新表中的统计信息并重新运行参数化查询以查看计划是否更好:

UPDATE STATISTICS ON dbo.Books WITH FULLSCAN;
UPDATE STATISTICS ON dbo.BookPublishRegions WITH FULLSCAN;