【问题标题】:What is the purpose of automatically creating statistics for a non-indexed column?为非索引列自动创建统计信息的目的是什么?
【发布时间】:2019-06-14 09:23:47
【问题描述】:

在 SQL Server 中,创建索引会自动为该索引创建统计对象,并使用它来决定最佳查询执行计划。

此外,会自动为 WHERE 子句中使用的列创建统计对象 - 例如:

SELECT *
FROM AWSales 
WHERE ProductID = 898

上面的查询会自动为 ProductID 创建一个统计对象。这有什么用?

既然非索引列是未排序的,而且它也不是 B 树结构,那么统计信息如何帮助选择比表扫描更好的查询计划?

我认为统计的目的是让引擎选择是否使用索引;以及是否使用搜索或扫描。我缺少什么知识?

【问题讨论】:

  • 了解查询运算符是否将返回 1 或 100 万行(或这些行的 10 或 1000 个不同的值)是很有用的,而不管如何使用索引来选择数据。例如,决定使用散列连接、循环连接还是合并连接以及为结果集保留多少内存至关重要。对于这个特定的查询,统计数据可能没有用,但它们通常非常有用(并且足够便宜,可以通过抽样产生),优化器会继续创建它们。在编译时对统计数据做出决定会复杂得多。

标签: sql-server indexing


【解决方案1】:

它的用途与为索引创建的统计信息相同。它将使用统计信息进行估计,以根据 CPU 时间和 I/O 选择最佳执行计划。将选择成本最低的计划。

当表上的索引不覆盖 where 子句中的列时,因此 ProductID,在您的示例中,它将在列上创建统计信息以创建直方图以嗅探您提供的值的估计值,除非它已经有一个缓存计划。

在您的执行计划中,您可以通过查看计划中 SELECT 对象(最左边的对象)的属性来查看引擎用于选择计划的统计信息。展开 OptimizerStatsUsage 属性。

【讨论】:

  • HI,但非索引列未排序。它们也不是 B-Tree 结构。那么统计究竟是如何帮助的。你能给我一个例子吗?我认为它总是会进行表扫描。
  • @variable,在您的简单查询中,引擎将进行扫描。但是假设您必须连接其他表,那么引擎如何选择连接类型?它应该选择 HASH、MERGE 还是 LOOP 连接?这取决于引擎将从统计中获取的行数。
  • 有道理。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-22
  • 2018-11-14
相关资源
最近更新 更多