gpt4 book ai didi

sql-server - SQL Server 查询计划差异

转载 作者:行者123 更新时间:2023-12-02 19:30:43 24 4
gpt4 key购买 nike

当从参数化查询更改为非参数化查询时,我无法理解 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 秒。但是,如果我将参数的两次使用替换为精确值,即将两个 '= @p0' 部分替换为 '= '1fc66e37-6eaf-4032-b374-e7b60fbd25ea' ' 我会得到不同的估计查询计划,并且查询现在运行时间要长得多(超过 60 秒,还没看完)。

为什么执行看似无害的替换会产生效率低得多的查询计划和执行?我已使用“DBCC FreeProcCache”清除了过程缓存,以确保我没有缓存错误的计划,但该行为仍然存在。

我真正的问题是我可以忍受 10 秒的执行时间(至少在很长一段时间内),但我无法忍受 60 秒以上的执行时间。我的查询将(如上所述)由 Linq2SQL 生成,因此它在数据库上执行为

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'

这会产生同样糟糕的执行时间(我认为这很奇怪,因为这似乎使用参数化查询。

我并不是在寻找有关创建哪些索引等的建议,我只是想了解为什么三个看似相似的查询的查询计划和执行如此不同。

编辑:我已经上传了非参数化和参数化查询的执行计划,以及具有不同 GUID Heinz 的参数化查询的执行计划(如 here 建议)

希望它能帮助你帮助我:)

最佳答案

如果您提供显式值,SQL Server 可以使用该字段的统计信息来做出“更好”的查询计划决策。不幸的是(正如我最近亲身经历的那样),如果统计信息中包含的信息具有误导性,有时 SQL Server 就会做出错误的选择。

如果您想更深入地研究这个问题,我建议您检查一下使用其他 GUID 时会发生什么:如果它对不同的具体 GUID 使用不同的查询计划,则表明使用了统计数据。在这种情况下,您可能需要查看 sp_updatestats 和相关命令。

编辑:看看DBCC SHOW_STATISTICS :“慢”和“快”GUID 可能位于直方图中的不同桶中。我有had a similar problem ,我通过添加 INDEX table hint 解决了这个问题到 SQL,它“引导”SQL Server 寻找“正确”的查询计划。基本上,我研究了“快速”查询期间使用的索引,并将它们硬编码到 SQL 中。这远非最佳或优雅的解决方案,但我还没有找到更好的解决方案......

关于sql-server - SQL Server 查询计划差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1667163/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com