PostgreSQL:为什么这个简单的查询不使用索引?

Dav*_*vid 9 database postgresql relational-database database-performance

我有一个带有列c的表t,它是一个int并且在其上有一个btree索引.

为什么以下查询不使用此索引?

explain select c from t group by c;
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

HashAggregate  (cost=1005817.55..1005817.71 rows=16 width=4)
  ->  Seq Scan on t  (cost=0.00..946059.84 rows=23903084 width=4)
Run Code Online (Sandbox Code Playgroud)

我对索引的理解是有限的,但我认为这些查询是索引的目的.

Mar*_*ers 6

可以使用称为松散索引扫描的优化来执行此查询.但PostgreSQL尚未实现此优化,因此它使用表扫描.

在主要的数据库中,据我所知,只有MySQL实现了松散的索引扫描(也许也是Oracle?).PostgreSQL 尚未实现此功能.

  • @a_horse_with_no_name:不,仅索引扫描是完全不同的,只能提供非常小的加速.松散的索引扫描可以提供几个数量级的改进.对于一百万行和100个不同的值,SQL Server中的查询可能需要大约1秒,而在MySQL中它只需要几毫秒.Oracle有一个索引跳过扫描几乎是一样的,但我不确定索引跳过扫描查询计划可以在这里使用 - 我认为它需要在查询中引用至少两列.然而,基础算法大致相同. (6认同)
  • @Scott Marlowe:但重点是,如果可以使用松散的索引扫描,你*不必*每行都打.这就是为什么MySQL可以比PostgreSQL快几百或几千倍的速度来进行这种查询(在非常大的表上,`c`的值非常少).这是一个低优先级的功能请求,因为架构设计的简单更改(引入新表)可以解决问题. (3认同)

Pet*_*aut 5

查询当然可以使用索引。不在您的特定情况下的原因取决于数据的特定大小和分布。可以SET enable_seqscan TO off用来调查。

  • 在什么情况下不使用索引是不划算的?至少当我们谈论这个例子中的大小时,我无法想象任何分布。 (2认同)