從參數化查詢更改爲非參數化查詢時,我無法理解SQL Server中我的語句的估計查詢計劃的行爲。SQL Server查詢計劃差異
我有以下查詢:
DECLARE @p0 UniqueIdentifier = '1fc66e37-6eaf-4032-b374-e7b60fbd25ea'
SELECT [t5].[value2] AS [Date], [t5].[value] AS [New]
FROM (
SELECT COUNT(*) AS [value], [t4].[value] AS [value2]
FROM (
SELECT CONVERT(DATE, [t3].[ServerTime]) AS [value]
FROM (
SELECT [t0].[CookieID]
FROM [dbo].[Usage] AS [t0]
WHERE ([t0].[CookieID] IS NOT NULL) AND ([t0].[ProductID] = @p0)
GROUP BY [t0].[CookieID]
) AS [t1]
OUTER APPLY (
SELECT TOP (1) [t2].[ServerTime]
FROM [dbo].[Usage] AS [t2]
WHERE ((([t1].[CookieID] IS NULL) AND ([t2].[CookieID] IS NULL))
OR (([t1].[CookieID] IS NOT NULL) AND ([t2].[CookieID] IS NOT NULL)
AND ([t1].[CookieID] = [t2].[CookieID])))
AND ([t2].[CookieID] IS NOT NULL)
AND ([t2].[ProductID] = @p0)
ORDER BY [t2].[ServerTime]
) AS [t3]
) AS [t4]
GROUP BY [t4].[value]
) AS [t5]
ORDER BY [t5].[value2]
由LINQ2SQL表達式生成該查詢和從LINQPad萃取。這會產生一個很好的查詢計劃(據我所知),並在數據庫中執行大約10秒鐘。但是,如果我用參數替換了兩個參數,那就是用'='1fc66e37-6eaf-4032-b374-e7b60fbd25ea'替換兩個'= @ p0'部分',我得到了一個不同的估計查詢計劃,查詢現在運行得更長(超過60秒,沒有看到它通過)。
爲什麼執行看似無辜的替換會產生效率更低的查詢計劃和執行?我用'DBCC FreeProcCache'清除了程序緩存,以確保我沒有緩存壞計劃,但行爲依然存在。
我真正的問題是我可以在10秒的執行時間內生活(至少在很長的一段時間內),但我不能忍受60+秒的執行時間。我的查詢會(如上面所暗示的)通過,因此作爲
exec sp_executesql N'
...
WHERE ([t0].[CookieID] IS NOT NULL) AND ([t0].[ProductID] = @p0)
...
AND ([t2].[ProductID] = @p0)
...
',N'@p0 uniqueidentifier',@p0='1FC66E37-6EAF-4032-B374-E7B60FBD25EA'
產生同樣不佳的執行時間(我認爲這是雙重奇怪,因爲這似乎是使用參數化查詢的數據庫上執行的LINQ2SQL生產。
我不是找提醒在其索引的創建或類似的,我只是想理解爲什麼查詢計劃和執行是三個看似相似的查詢,以便不同的
編輯:我已經上傳了非參數化和執行計劃用不同的GUID here
參數化查詢以及用於參數化查詢(如Heinz建議)執行計劃希望它可以幫助你幫我:)
您可以發佈您收到的查詢計劃嗎?剛剛運行'SET SHOWPLAN_TEXT ON GO SELECT ...' – Quassnoi 2009-11-03 13:06:44
完成...添加了執行計劃的鏈接... – 2009-11-03 13:42:03