什么时候创建 STATISTICS 比创建索引更好?

Sol*_*zky 41 sql-server best-practices statistics index-statistics

我找到了很多关于什么 的信息STATISTICS:如何维护它们,如何从查询或索引手动或自动创建它们,等等。但是,我一直无法找到有关何时的任何指导或“最佳实践”信息创建它们:在哪些情况下,手动创建的 STATISTICS 对象比索引更受益。我已经看到手动创建的过滤统计有助于对分区表的查询(因为为索引创建的统计覆盖了整个表而不是每个分区——brillaint!),但肯定有其他场景可以从统计对象中受益,同时不需要索引的详细信息,也不值得维护索引或增加阻塞/死锁机会的成本。

@JonathanFite 在评论中提到了索引和统计数据之间的区别:

索引将通过创建排序与表本身不同的查找来帮助 SQL 更快地找到数据。统计信息帮助 SQL 确定满足查询需要多少内存/工作量。

这是很好的信息,主要是因为它帮助我澄清了我的问题:

如何知道这(或在任何其他技术信息什么S和如何S的相关的行为和性质STATISTICS)帮助确定何时选择CREATE STATISTICSCREATE INDEX创建索引将创建相关的时候,尤其是STATISTICS对象?什么情况下只有统计信息而没有索引会更好地服务?

如果可能的话,有一个场景的工作示例,其中STATISTICS对象比INDEX.


由于我是一名视觉学习者/思考者,我认为将esSTATISTICSINDEXes之间的差异并排查看可能有助于确定何时STATISTICS是更好的选择。

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.
Run Code Online (Sandbox Code Playgroud)

以下是我在寻找时发现的一些资源,其中一个甚至提出了同样的问题,但没有得到回答:

SQL Server 索引与统计

我们不敢问的 SQL Server 统计问题

统计数据。多列直方图可能吗?

** 需要明确的是,我对此没有答案,实际上我希望从有希望的几个人那里获得反馈,以提供互联网上似乎奇怪地缺少的信息。

Kin*_*hah 21

你的问题围绕着 - 什么时候只创建统计数据和创建索引(创建统计数据)是一件好事。

从我的 sql server internals notes (SQLSkills class- IE1 and IE2) 和SQL Server internals book,以下是我有限的理解:

SQL Server 统计信息只不过是包含有关索引键值和常规列值的重要信息的系统对象。

SQL Server 使用基于成本的模型尽可能快地选择“足够好”的执行计划。Cardanility 估计(估计在查询执行的每个步骤中要处理的行数)是查询优化中最重要的因素,它反过来影响连接策略、内存授予要求、工作线程选择以及访问数据时的索引选择.

当 SQL Server 估计一个很大的数字时,它不会使用非聚集索引。将需要 KEY 或 RID 循环操作,因此它维护索引(和列)的统计信息,这将有助于此类估计。

关于 stats 有两个重要的事情:

  1. 直方图仅存储有关最左侧统计(索引)列的数据分布的信息。它还存储有关键值的多列密度的信息。所以本质上,直方图只存储最左边的统计列的数据分布。

  2. 无论表大小如何,SQL Server 都将在直方图中保留最多 200 步。每个直方图步骤覆盖的间隔随着表格的增长而增加,这导致大型表格的“不太准确”的统计数据。

    请记住,索引选择性是一个与密度成反比的指标,即列具有的唯一值越多,其选择性就越高。

当特定查询不经常运行时,您可以选择创建列级统计信息而不是索引。列级统计信息可帮助查询优化器找到更好的执行计划,即使这些执行计划由于涉及索引扫描而不是最佳的。同时,统计不会增加数据修改操作的开销,有助于避免索引维护。这种方法仅适用于很少执行的查询。

参考 :

注意:像Paul WhiteAaron Bertrand 这样的人可以插话为您的好问题提供更多色彩。


Jam*_*s Z 11

我会说当您需要能够限制数据量/根据字段快速获取正确数据时,您需要一个索引。

当您需要优化器了解数据的性质以便能够以最佳方式执行操作时,您需要统计信息。

我发现,当您的数据存在严重影响计划的偏差时,过滤统计会有所帮助,例如在堆栈溢出时,很少有用户拥有大量帖子,因此仅使用每个用户的平均帖子并不是最好的估计。所以你可以根据用户名创建一个关于 userId 的过滤统计,然后 SQL Server 应该知道当这个用户名在查询中时,这是它将获得的用户 ID,它应该能够弄清楚, posts 表中的索引字段将有大量具有该 id 的行,因为那里存在直方图。对于平均值,这是不可能做到的。


Ken*_*aro 6

Itzik Ben-Gan 的 70-461 培训书

手动创建统计数据的可能原因只有几个。一个例子是当查询谓词包含多个具有跨列关系的列时;多列的统计信息可以帮助改进查询计划。多列的统计数据包含单列统计数据中不可用的跨列密度。但是,如果列已经在同一个索引中,则多列统计对象已经存在,因此您不应手动创建额外的对象。

  • 我认为 Kin 的解释会进一步解释你所追求的。也许是一个经常插入但很少查询的堆? (2认同)