首页 > 解决方案 > 为什么 SELECT COUNT(DISTINCT) 中不使用索引?

问题描述

这就是我在 PostgreSQL 10.9 ( xis VARCHAR(100)) 中所做的:

SELECT COUNT(DISTINCT x) FROM t

该表有超过 150 万条记录,并且有一个索引:

CREA­TE INDE­X idx_1 ON t­ USIN­G btre­e (x)

该请求需要 7 秒以上。这EXPLAIN就是说:

Aggr­egat­e (cos­t=23­675.­97..­2367­5.97­ rows­=1 widt­h=8)­
->­; Seq Scan­ on t (cos­t=0.­00..­2293­0.97­ rows­=148­9990­ widt­h=23­)

怎么了?为什么不使用索引?

标签: postgresql

解决方案


这取决于两个因素:

  1. 表是否有“宽行”
  2. 桌子是否被吸尘

无论如何,查询必须扫描整个索引或整个表,因为 PostgreSQL 中没有索引跳过扫描

PostgreSQL 可以扫描索引或表。

  • 如果表最近没有被清理,索引扫描将始终必须访问表以确定该行是否可见。在这种情况下,顺序扫描总是会更快。

  • 如果表最近被清理过,并且可见性地图的大多数块都标记为“全部可见”,那么您可以获得仅索引扫描

    • 如果表行很窄,您不太可能只扫描索引,因为读取索引不会比读取表便宜(顺序读取更快)。

    • 对于具有宽行的表,您将获得仅索引扫描。


推荐阅读