我有一个相对简单的查询,当我在where子句中使用文字值运行它时,运行大约2.5分钟。但是当我使用包含相同值的局部变量运行它时,查询会挂起或大概永远运行。 (我还没试过让它运行超过90分钟。)
这里是名称混淆的查询(因为规则)。我尝试用INNER JOIN替换EXISTS,但它没有帮助。下面的变量是局部变量,而不是参数。这不是一个参数嗅探问题。但是当变量用它们的文字值(两个DATETIME和三个INT)替换时,查询运行正常。
DECLARE @SubsetStart DATETIME = '2013-01-01 00:00:00'
DECLARE @SubsetEnd DATETIME = '2013-12-31 23:59:59'
DECLARE @SCD INT = 217
DECLARE @MFP INT = 8
DECLARE @EXP INT = 39298
SELECT
MainTable.MFID ManufacturerID
,SUM(MainTable.AMT) AMT
FROM
MainTable
WHERE
EXISTS (
SELECT TID
FROM MTMTable
WHERE MTMTable.TID = MainTable.TID
AND MTMTable.DEL = 0
AND EXISTS (
SELECT CID
FROM RelatedTable
WHERE RelatedTable.CID = MTMTable.CID
AND DEL = 0
AND RelatedTable.TD BETWEEN '2013-01-1' AND '2013-12-31 23:59:59'
)
)
AND EXISTS (
SELECT AID
FROM OtherTable
WHERE OtherTable.AID = MainTable.CAID
AND OtherTable.AHTID = 8
AND OtherTable.DEL = 0)
AND MainTable.DAID <> 39298
AND MainTable.SID = 217
GROUP BY
MainTable.MFID
我完全不知道为什么这个简单的查询应该以这种方式运行。
答案 0 :(得分:0)
问题在于,当您使用局部变量时,优化器会忽略它们的值并使用一般统计假设。基本上在编译时它不知道那些变量的值。您可以使用查询中的OPTION(RECOMPILE)提示来验证这一点,这将使用变量中的值重新编译查询。
您可以阅读有关在存储过程中使用局部变量可能会影响性能的原因:
https://www.brentozar.com/archive/2014/06/tuning-stored-procedures-local-variables-problems/
在这里:
http://www.sqlbadpractices.com/using-local-variables-in-t-sql-queries/