2010-09-14 209 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获得的计划相同的计划,并且性能会更好。