2010-09-14 158 views
6

我有一個在SQL Server Management STudio中超快的查詢,在sp_ExecuteSQL下運行時超慢。SQL Server sp_ExecuteSQL和執行計劃

這是否與在spExecuteSQL下運行時不會發生執行計劃緩存有關?

+7

我不知道什麼時候「sp_executesql不緩存計劃」神話會永遠死去 - 讀[動態SQL的詛咒和祝福] – 2010-09-14 15:52:24

+0

@OMG Ponies - 參數嗅探可能是sp_ExecuteSQL的問題? – JNK 2010-09-14 16:48:39

+0

@JNK:自從經歷了這種行爲之後,無論如何我都默認使用了反參數嗅探。 – 2010-09-14 17:25:38

回答

8

編號

您可以看到兩個執行計劃並使用以下查詢進行比較。

SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa 
where text like '%Some unique string in your query%' 
              and attribute='set_options' 

sp_executesql版本將有一個objtype 「準備」

+3

爲什麼執行計劃會有如此不同?例如,我直接從Sql Management Studio(需要3秒)查看我的查詢執行計劃,並從sp_executeSql執行計劃(需要5分鐘以上)。來自sp_executeSql的計劃完全忽略了直接調用發現的一些關鍵索引。有人可以解釋爲什麼來自management studio的調用找到了鍵,但通過sp_ExecuteSql調用的不是? – 2011-03-28 16:46:07

+0

@NathanTregillus - 可能是參數嗅探,您可以查看緩存的計劃XML以查看計劃實際編譯的參數的值。 – 2012-12-19 09:46:59

+0

感謝@MartinSmith的回覆。這實際上是由於我們如何在視圖中使用contextInfo作爲過濾器,以及它如何不被考慮進執行計劃中 – 2012-12-26 23:55:35

1

經歷了同樣的行爲。 (設置選項相等) 定期查詢生成並行計劃並使用sp_executesql它生成了一個連續計劃。

declare @xyzParam1 datetime,@xyzParam2 datetime 
select @xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 
SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2 
; 

VS

exec sp_executesql N'SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2',N'@xyzParam1 datetime,@xyzParam2 datetime',@xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 

我設法獲得最佳結果修改所述用於視圖,因爲它包含例如留下了一直期待的數據。 (轉換爲INNER連接)

現在,常規查詢會選擇與使用sp_executesql獲得的計劃相同的計劃,並且性能會更好。