临时表的索引和统计信息

Sir*_*lot 7 sql-server index-tuning temporary-tables sql-server-2016 query-store

我刚刚将我们的数据仓库升级到 SQL 2016。我在查询存储中看到了一些非常有趣的图表(我喜欢这个功能!)。下面是我见过的最奇怪的例子。同一查询的 22 个计划。

在此处输入图片说明

这让我开始考虑 ETL 过程的性能调优、临时表的优缺点以及如何影响执行计划行为。

我的 ETL 过程使用了许多存储过程,这些过程混合使用标准和临时 #tables 作为临时表。#tables 通常使用一次然后删除。有些只有几千行。有些是数百万。SSMS 建议缺少索引,但是在较小的表上,它们是否会产生足够的差异以值得添加它们?更好的统计数据就足够了吗?

我刚刚阅读了有关临时表统计信息的Brent Ozar 博客文章,以及 Paul White 关于存储过程中的临时表的文章

它说统计信息是在查询#table 时自动创建的,然后大概由优化器使用。

我的问题是:在#table 上创建索引是否有很多意义或好处。和/或:在查询中使用统计信息之前,是否值得显式更新统计信息作为存储过程中的一个步骤,因为它们只使用一次。

额外的步骤和开销是否值得?它会导致明显更好或不同的执行计划吗?

Tar*_*zer 6

在临时表上创建索引可能会有好处,但可能不适用于临时表。不幸的是,这是一个“视情况而定”的答案。您将需要进行测试。如果您发布了有关如何与临时表交互的代码,我们可以帮助确定是否有任何索引会有所帮助。索引可能有用的一个示例是,如果您将临时表连接到另一个表。如果您要对连接的列进行索引,则可能会提高性能,尤其是在临时表中有很多行的情况下。

您可能不需要更新临时表的统计信息。这也是一个“视情况而定”的答案,尽管我从未在我看过的成千上万个存储过程中的任何一个中看到临时表的更新统计信息,也不需要添加它来解决性能问题。


Mic*_*een 5

仅统计数据是不够的。存储引擎必须有某种方式来获取与查询谓词匹配的行。例如,如果无法确定是哪三行,那么知道三行与表中一百万行中的条件匹配是没有任何价值的。如果没有索引,唯一的策略就是表扫描。将读取一百万行。99.9997%将被丢弃。通过匹配的索引,可以跟随指针来挑选出所需的三行。

对于只需要几页的小表,必须考虑读取索引页的工作量。假设一个与查询完全匹配的非聚集索引只需要两个级别。跟随按键需要阅读两页。然后是聚集索引。很可能还要再读两页。因此,如果整个表少于 4 页,则不太可能使用非聚集索引。