从参数化查询更改为非参数化查询时,我无法理解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