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
,因此无论如何都必须检索数据行。使用索引需要加载索引和数据行,然后从索引间接加载到数据行。这有点复杂。而且有两排,根本不值得努力
索引的威力在于处理大量数据,而不是处理少量数据。
回答大问题:不需要数据库优化器来使用索引。他们使用某种措施(通常是基于成本的优化)来确定索引是否合适。在较大的示例中,优化器已确定索引不合适。如果统计信息与基础数据不同步,则可能会发生这种情况。
我关注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
,因此无论如何都必须检索数据行。使用索引需要加载索引和数据行,然后从索引间接加载到数据行。这有点复杂。而且有两排,根本不值得努力
索引的威力在于处理大量数据,而不是处理少量数据。
回答大问题:不需要数据库优化器来使用索引。他们使用某种措施(通常是基于成本的优化)来确定索引是否合适。在较大的示例中,优化器已确定索引不合适。如果统计信息与基础数据不同步,则可能会发生这种情况。