在开发新的查询时,我编写了它并在SQL查询分析器中对其进行了分析。查询表现非常好,没有任何表扫描,但是当我将其封装在存储过程中时,性能非常糟糕。当我查看执行计划时,我可以看到SQL Server选择了一个不同的计划,它使用表扫描而不是TableB上的索引查找(我已经强制混淆了表和列名,但没有查询逻辑已经改变)。直接执行语句和从存储过程执行语句时的不同执行计划
这里的查询
SELECT
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)) AS Day,
DATEPART(hh, TableA.Created) AS [Hour],
SUM(TableB.Quantity) AS Quantity,
SUM(TableB.Amount) AS Amount
FROM
TableA
INNER JOIN TableB ON TableA.BID = TableB.ID
WHERE
(TableA.ShopId = @ShopId)
GROUP BY
DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)),
DATEPART(hh, TableA.Created)
ORDER BY
DATEPART(hh, TableA.Created)
当我运行查询“原始”我得到了下面的跟踪统计
Event Class Duration CPU Reads Writes SQL:StmtCompleted 75 41 7 0
当我使用下面的命令
运行查询作为存储过程DECLARE @ShopId int
SELECT @ShopId = 1
EXEC spStats_GetSalesStatsByHour @ShopId
我收到以下跟踪统计
Event Class Duration CPU Reads Writes SQL:StmtCompleted 222 10 48 0
我也得到了同样的结果,如果我存储查询在一个nvarchar和使用sp_executesql如下执行(它执行如存储过程)
DECLARE @SQL nvarchar(2000)
SET @SQL = 'SELECT DATEADD(dd, ...'
exec sp_executesql @SQL
该存储过程并不包含除什么上面的select语句。什么会导致sql server仅仅因为语句被作为存储过程执行而选择劣质执行计划?
目前,我们正在的SQL Server 2000
谢谢老兄,那个窍门 很可笑的快速答案! – 2009-01-07 18:01:44