Sql 直接执行语句和从存储过程执行语句时的不同执行计划

Sql 直接执行语句和从存储过程执行语句时的不同执行计划,sql,sql-server,tsql,stored-procedures,sql-execution-plan,Sql,Sql Server,Tsql,Stored Procedures,Sql Execution Plan,在工作中开发新查询时,我编写了它,并在SQL查询分析器中对其进行了分析。查询在没有任何表扫描的情况下执行得非常好,但当我将其封装在存储过程中时,性能非常糟糕。当我查看执行计划时,我可以看到SQL Server选择了一个不同的计划,该计划使用表扫描而不是表B上的索引查找(我被迫对表和列名进行了一些模糊处理,但查询逻辑没有任何更改) 这是问题 SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, TableA.Created)) AS Day, DA

在工作中开发新查询时,我编写了它,并在SQL查询分析器中对其进行了分析。查询在没有任何表扫描的情况下执行得非常好,但当我将其封装在存储过程中时,性能非常糟糕。当我查看执行计划时,我可以看到SQL Server选择了一个不同的计划,该计划使用表扫描而不是表B上的索引查找(我被迫对表和列名进行了一些模糊处理,但查询逻辑没有任何更改)

这是问题

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)
当我运行查询“raw”时,我得到以下跟踪统计信息

Event Class Duration CPU Reads Writes SQL:StmtCompleted 75 41 7 0 Event Class Duration CPU Reads Writes SQL:StmtCompleted 222 10 48 0 我得到以下跟踪数据

Event Class Duration CPU Reads Writes SQL:StmtCompleted 75 41 7 0 Event Class Duration CPU Reads Writes SQL:StmtCompleted 222 10 48 0 除上面的select语句外,存储过程不包含任何内容。什么原因会导致sql server仅仅因为语句是作为存储过程执行的而选择较差的执行计划


我们目前运行的是SQL Server 2000,这通常与参数嗅探有关。处理这件事可能会非常令人沮丧。有时可以通过重新编译存储过程来解决,有时甚至可以在存储过程中使用重复变量,如下所示:

alter procedure p_myproc (@p1 int) as
declare @p1_copy int;
set @p1_copy = @p1;
然后在查询中使用@p1\u copy。看起来很可笑,但它确实有效

检查我最近关于同一主题的问题:

是的——我在Oracle DB 11g上也看到了这一点——同样的查询在SQL提示符下在DB server的两个节点上快速运行,但当从包中调用时,它实际上挂起了


必须清除共享池才能获得相同的行为:原因是某些作业/脚本正在运行,而较旧的副本被锁定在一个节点上的库缓存/内存中,且执行计划较差。

谢谢你,这就为可笑的快速回答赢得了荣誉!