如何解决Postgres 查询计划为什么行估计如此错误
Postgres 版本:12
查询: 解释(分析为真、详细为真、成本为真、缓冲区为真、时间为真) SELECT MIN("id"),MAX("id") FROM "public"."hotel_slot_inventory" WHERE ( "updated_at" >= '2021-03-02 13:30:03' AND "updated_at"
查询计划:
Result (cost=512.44..512.45 rows=1 width=8) (actual time=57839.244..57839.250 rows=1 loops=1)
Output: $0,$1
Buffers: shared hit=1 read=454374 written=185
I/O Timings: read=54564.571 write=2.686
InitPlan 1 (returns $0)
-> Limit (cost=0.57..256.22 rows=1 width=4) (actual time=57599.761..57599.764 rows=1 loops=1)
Output: hotel_slot_inventory.id
Buffers: shared read=453546 written=185
I/O Timings: read=54330.640 write=2.686
-> Index Only Scan using hotel_slot_inventory_id_updated_at_idx on public.hotel_slot_inventory (cost=0.57..3285663.29 rows=12852 width=4) (actual time=57599.758..57599.759 rows=1 loops=1)
Output: hotel_slot_inventory.id
Index Cond: ((hotel_slot_inventory.id IS NOT NULL) AND (hotel_slot_inventory.updated_at >= '2021-03-02 13:30:03'::timestamp without time zone) AND (hotel_slot_inventory.updated_at < '2021-03-03 06:15:19.127884'::timestamp without time zone))
Heap Fetches: 0
Buffers: shared read=453546 written=185
I/O Timings: read=54330.640 write=2.686
InitPlan 2 (returns $1)
-> Limit (cost=0.57..256.22 rows=1 width=4) (actual time=239.468..239.470 rows=1 loops=1)
Output: hotel_slot_inventory_1.id
Buffers: shared hit=1 read=828
I/O Timings: read=233.931
-> Index Only Scan Backward using hotel_slot_inventory_id_updated_at_idx on public.hotel_slot_inventory hotel_slot_inventory_1 (cost=0.57..3285663.29 rows=12852 width=4) (actual time=239.465..239.465 rows=1 loops=1)
Output: hotel_slot_inventory_1.id
Index Cond: ((hotel_slot_inventory_1.id IS NOT NULL) AND (hotel_slot_inventory_1.updated_at >= '2021-03-02 13:30:03'::timestamp without time zone) AND (hotel_slot_inventory_1.updated_at < '2021-03-03 06:15:19.127884'::timestamp without time zone))
Heap Fetches: 0
Buffers: shared hit=1 read=828
I/O Timings: read=233.931
Planning Time: 10.577 ms
Execution Time: 57839.332 ms
(28 rows)
在两个 InitPlan 中,rows=12852 而实际 rows=1。这是为什么? Index only scan后单独添加了limit子句。
编辑索引膨胀详细信息:
真实大小:3751411712 = 3.49 GB
额外大小:470237184 = 448 MB
额外比率:12.53
填充因子:90
膨胀大小:107053056 = 102 MB
膨胀比率:2.85
表格膨胀大小: 膨胀大小:475283456 = 453 MB
膨胀比率:5.088
解决方法
看起来索引膨胀变形了。试试
REINDEX INDEX hotel_slot_inventory_id_updated_at_idx;
或
VACUUM (FULL) hotel_slot_inventory;
,
这是正常的。 “仅索引扫描”行的预期行数给出了预期满足索引条件的行数,如果扫描完成。实际行反映了 LIMIT 使其提前停止的事实。请注意,LIMIT 的成本估算低于索引扫描的成本估算,因为该估算也是针对完整扫描给出的,然后由 LIMIT “回退”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。