我正在阅读 Grant Friitchey 的《剖析 SQL Server 执行计划》,它对我了解某些查询速度缓慢的原因有很大帮助。
但是,我对这种情况感到困惑,简单的重写执行速度要快得多。
这是我第一次尝试,需要 21 秒。它使用派生表:
-- 21 secs
SELECT *
FROM Table1 AS o JOIN(
SELECT col1
FROM Table1
GROUP BY col1
HAVING COUNT( * ) > 1
) AS i ON ON i.col1= o.col1
我的第二次尝试速度快了 3 倍,并且只是将派生表移出到临时表。现在速度提高了 3 倍:
-- 7 secs
SELECT col1
INTO #doubles
FROM Table1
GROUP BY col1
HAVING COUNT( * ) > 1
SELECT *
FROM Table1 AS o JOIN #doubles AS i ON i.col1= o.col1
我的主要兴趣在于为什么从派生表迁移到临时表可以大大提高性能,而不是如何使其更快。
如果有人可以向我展示如何使用(图形)执行计划诊断此问题,我将不胜感激。
Xml执行计划: https://www.sugarsync.com/pf/D6486369_1701716_16980
编辑 1
当我在分组依据中指定的 2 列上创建统计信息时,优化器在放弃过程缓存后开始做“正确的事情”(不要忘记,如果您是初学者!)。我简化了问题中的查询,回想起来这并不是一个很好的简化。附加的 sqlplan 显示了 2 列,但这并不明显。
现在的估计更加准确,性能也与临时表解决方案相当。如您所知,优化器会自动在单列上创建统计信息(如果未禁用),但 DBA 必须创建 2 列统计信息。
这两列上的(非聚集)索引使查询执行相同的操作,但在这种情况下,统计数据同样好,并且不会受到索引维护的负面影响。 我将继续进行 2 列统计,看看它的表现如何。 @Grant你知道索引上的统计数据是否比列统计数据更可靠吗?
编辑2
一旦问题解决,我总是跟进如何在未来更快地诊断类似的问题。
这里的问题是估计的行数是错误的。当您将鼠标悬停在一行上时,图形执行计划会显示这些内容,仅此而已。
一些可以提供帮助的工具:
- 设置统计配置文件
我听说这个将过时并被它的 XML 变体取代,但我仍然喜欢网格格式的输出。 这里“Rows”列和“EstimateRows”列之间的巨大差异会显示问题
- 外部工具:SQL Sentry Plan Explorer http://www.sqlsentry.net/
这是一个很好的工具,特别是如果您是初学者。它突出了问题
- 外部工具:SSMS 工具包 http://www.ssmstoolspack.com/
一个更通用的工具,但再次引导用户解决潜在问题
亲切的问候,汤姆
最佳答案
查看第一个执行计划的值,它看起来像是统计数据。您的估计行数为 800,实际行数为 120 万。我想您会发现更新统计信息将改变第一个查询计划的生成方式。
关于sql-server - 为什么从派生表迁移到临时表解决方案时性能会提高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9484056/