Postgresql:序列扫描而不是索引扫描

Postgresql: Seq Scan instead of Index Scan

我关注table:

create table if not exists inventory
(
    expired_at timestamp(0),
    -- ...
);

create index if not exists inventory_expired_at_index
    on inventory (expired_at);

但是当我 运行 以下查询时:

EXPLAIN UPDATE "inventory" SET "status" = 'expired' WHERE "expired_at" < '2020-12-08 12:05:00';

我得到下一个执行计划:

Update on inventory  (cost=0.00..4.09 rows=2 width=126)
  ->  Seq Scan on inventory  (cost=0.00..4.09 rows=2 width=126)
        Filter: (expired_at < '2020-12-08 12:05:00'::timestamp without time zone)

大数据集也是如此:

EXPLAIN SELECT * FROM "inventory"  WHERE "expired_at" < '2020-12-08 12:05:00';
-[ RECORD 1 ]---------------------------------------------------------------------------
QUERY PLAN | Seq Scan on inventory  (cost=0.00..58616.63 rows=1281058 width=71)
-[ RECORD 2 ]---------------------------------------------------------------------------
QUERY PLAN |   Filter: (expired_at < '2020-12-08 12:05:00'::timestamp without time zone)

问题是:为什么不是Index Scan而是Seq Scan

评论有点长

简短的回答是 table 中有两行,所以没有什么区别。

较长的答案是您使用的是 update,因此无论如何都必须检索数据行。使用索引需要加载索引和数据行,然后从索引间接加载到数据行。这有点复杂。而且有两排,根本不值得努力

索引的威力在于处理大量数据,而不是处理少量数据。

回答大问题:不需要数据库优化器来使用索引。他们使用某种措施(通常是基于成本的优化)来确定索引是否合适。在较大的示例中,优化器已确定索引不合适。如果统计信息与基础数据不同步,则可能会发生这种情况。