Sql server 为什么从派生表移动到临时表解决方案时会提高性能?

Sql server 为什么从派生表移动到临时表解决方案时会提高性能?,sql-server,sql-execution-plan,database-performance,Sql Server,Sql Execution Plan,Database Performance,我正在阅读Grant Fritchey的“剖析SQL Server执行计划”,这对我了解某些查询的速度慢有很大帮助 然而,我被这个简单的重写执行得更快的例子难住了 这是我第一次尝试,需要21秒。它使用一个派生表: -- 21 secs SELECT * FROM Table1 AS o JOIN( SELECT col1 FROM Table1 GROUP BY col1 HAVING COUNT( * ) > 1 ) AS i ON O

我正在阅读Grant Fritchey的“剖析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执行计划:

编辑1

当我在group by中指定的2列上创建统计数据时,优化器在放弃过程缓存后开始做“正确的事情”(如果您是初学者,请不要忘记!)。我简化了问题中的查询,回想起来,这不是一个很好的简化。所附的sqlplan显示了这两列,但这并不明显

现在的估计更精确,性能与临时表解决方案相当。正如您所知,优化器会自动在单个列上创建统计信息(如果未禁用),但DBA必须创建两列统计信息

这两列上的(非聚集的)索引使查询执行相同的操作,但在本例中,stat也一样好,并且不会受到索引维护的不利影响。 我将继续使用2列统计数据,看看它的性能如何@Grant你知道索引上的统计数据是否比列统计数据更可靠吗

编辑2

我总是在问题解决后跟进如何在将来更快地诊断类似问题

这里的问题是,估计的路权是一种方式。当您将鼠标悬停在一行上时,图形执行计划将显示这些,仅此而已

一些有帮助的工具:

  • 将统计配置文件设置为
  • 我听说这个将被淘汰,并被它的XML变体所取代,但我仍然喜欢网格格式的输出。 在这里,列“Rows”和“EstimateRows”之间的巨大差异会说明问题所在

  • 外部工具:SQL Sentry计划资源管理器
  • 这是一个很好的工具,特别是如果你是初学者的话。它突出了问题

  • 外部工具:SSMS工具包
  • 一个更通用的工具,但再次指导用户潜在的问题


    您好,Tom查看第一个执行计划的值,它看起来像是统计数据。估计行数为800,实际行数为120万。我想您会发现,更新统计信息将改变第一个查询计划的生成方式。

    如果没有两个查询的查询计划,我们无法说出原因。这可能与在派生表上错误估计的临时表上具有准确的统计信息有关。在第一个示例中,将子查询的结果选择到临时表中的目的是什么?为什么不在子选择中按col1拥有COUNT(*)>1的col1从表1 GROUP中选择col1呢?我看不到计划,只有图形。如果没有计划本身,我只能猜测到底发生了什么。要看的是,第一个计划提前终止的原因是什么?用于加载到临时表的表上的统计信息是什么?如果统计数据已经过时,那么加载到temp表可以为您提供更干净的统计数据集。再一次,只要看看图表,这些都是猜测。+1格兰特。在第一个查询中,该计划显示一个哈希连接,但是两个集群扫描的管道宽度看起来几乎相同。对于散列连接,我希望一个管道很小,另一个管道很大。对我来说,这意味着过时或缺少统计数据,这会导致次优计划(联接算法选择不当,为排序和联接预先分配的内存不足,等等)。正如格兰特指出的,这张图并没有完全解释计划(估计的行数,实际的行数…。@buckley仅仅统计数据和索引中的统计数据之间没有差异。它们都是统计数据。我们更新了所有的统计数据,但估计值仍然不准确。我仍然认为这与糟糕的统计数据有关。你知道我们下一步要看什么吗?你用完整扫描更新了统计数据了吗?如果您进行了采样更新,它可能仍然会显示差异。如果没有,那么还有一些我从计划中看不到的事情正在发生。使用完整扫描在表上创建统计数据并没有改善执行计划。您是对的,SQL Server没有正确的评估来制定好的执行计划。我用答案更新了这个问题。