【问题标题】:Can indexes be used on aggregated calculations?索引可以用于聚合计算吗?
【发布时间】:2019-09-29 03:37:09
【问题描述】:

索引可以用来做这样的事情:

SELECT name FROM bigtable GROUP BY name

也就是说,它可以遍历 btree 或任何索引结构来获取值。但是,索引对这样的事情有帮助吗?

SELECT name, count(1) FROM bigtable GROUP BY name

请注意,出于此问题的目的,不会应用过滤器或排序。

我的想法是它不会因为需要表扫描(无论是否有索引)来“总结”所有值。这是正确的,还是我在这里遗漏了什么?索引对聚合计算有用吗?如何或如何不?

除了预先存储这些值之外,还有什么方法可以加快这些值的计算速度,或者这里真的只是磁盘速度的问题。

【问题讨论】:

  • 聚合总是执行扫描,table scanindex scan。在 MSSQL 中,您可以使用 include 列创建索引(每个示例中的数量),如果您 sum() 按索引键分组的数量列,这样做会比简单的表扫描执行得更好。

标签: sql sql-server database


【解决方案1】:

我的想法是它不会因为需要表扫描(无论是否有索引)来“总结”所有值。

不,您也可以只扫描索引。它包含(在您的示例中)每行的条目及其 name 列值。

与表格不同的是,索引已经按name 分组/排序,因此不需要额外的排序步骤。如果您尝试使用全表扫描来执行此操作,则需要大量内存或临时空间来运行每个名称的计数器。

第二部分在这里有很大的不同(并不是说扫描整个索引比扫描整个表更快,这当然也是如此,因为它更小并且可能已经缓存了)。

您应该能够通过查看执行计划轻松验证这一点。

请注意,出于此问题的目的,不会应用过滤器或排序。

如果您确实引用了查询中的其他列,则索引不再是“覆盖索引”,并且不能再(单独)用于满足查询。

【讨论】:

  • 知道了。所以如果我做了类似SELECT count(1), DISTINCT COUNT(country) GROUP BY name 这样的事情,索引就不会被使用,对吗?
  • 是的,至少不是唯一的。不过,(name, country) 上的复合索引会有所帮助。
  • 如果您执行SELECT name, count(1) FROM bigtable GROUP BY name ORDER BY count(1),您将保留索引扫描,但之后还有另一个排序步骤。而ORDER BY name 将是“免费的”(这就是它已经从索引扫描中出来的方式)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
相关资源
最近更新 更多