我有两个Aurora PG数据库,一个版本为12.8,另一个版本为13.4。我有一个这样的表:
CREATE TABLE IF NOT EXISTS table1
(
id character varying COLLATE pg_catalog."C" NOT NULL,
col1 character varying COLLATE pg_catalog."C" NOT NULL,
col2 bytea,
CONSTRAINT id_pkey PRIMARY KEY (id)
)
CREATE UNIQUE INDEX IF NOT EXISTS idx_col2
ON table1 USING btree
(col2 ASC NULLS LAST)
WHERE col2 IS NOT NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_col1
ON table1 USING btree
(col1 COLLATE pg_catalog."C" ASC NULLS LAST)
PG12表有大约800万行,而PG13表只有大约20万行。尽管如此,尽管对PG13表的查询始终命中我的索引,但PG12查询却没有。EXPLAIN ANALYZE
的示例结果
WHERE
col2 = '\x3be8f76fd6199cbbcd4134bf505266841579817de7f3e59fe3947db6b5279fe2' OR
col1 = 'ORrKzFeI37dV-bnk1heGopi61koa9fmO'
LIMIT 1;
-- in PG12:
Limit (cost=0.00..8.26 rows=1 width=32) (actual time=1614.602..1614.603 rows=0 loops=1)
-> Seq Scan on table1 (cost=0.00..308297.01 rows=37344 width=32) (actual time=1614.601..1614.601 rows=0 loops=1)
Filter: ((col2 = '\x3be8f76fd6199cbbcd4134bf505266841579817de7f3e59fe3947db6b5279fe2'::bytea) OR ((col1)::text = 'ORrKzFeI37dV-bnk1heGopi61koa9fmO'::text))
Rows Removed by Filter: 7481857
Planning Time: 0.478 ms
Execution Time: 1614.623 ms
-- PG13:
Limit (cost=8.58..12.60 rows=1 width=32) (actual time=0.022..0.022 rows=0 loops=1)
-> Bitmap Heap Scan on table1 (cost=8.58..12.60 rows=1 width=32) (actual time=0.021..0.021 rows=0 loops=1)
Recheck Cond: ((col2 = '\x3be8f76fd6199cbbcd4134bf505266841579817de7f3e59fe3947db6b5279fe2'::bytea) OR ((col1)::text = 'ORrKzFeI37dV-bnk1heGopi61koa9fmO'::text))
-> BitmapOr (cost=8.58..8.58 rows=1 width=0) (actual time=0.018..0.018 rows=0 loops=1)
-> Bitmap Index Scan on idx_authcol1_col2 (cost=0.00..4.15 rows=1 width=0) (actual time=0.009..0.009 rows=0 loops=1),
Index Cond: (col2 = '\x3be8f76fd6199cbbcd4134bf505266841579817de7f3e59fe3947db6b5279fe2'::bytea)
-> Bitmap Index Scan on ix_authcol1_col1 (cost=0.00..4.43 rows=1 width=0) (actual time=0.008..0.008 rows=0 loops=1)
Index Cond: ((col1)::text = 'ORrKzFeI37dV-bnk1heGopi61koa9fmO'::text)
Planning Time: 0.520 ms,
Execution Time: 0.053 ms
我不能在本地重现这些结果,也不能弄清楚为什么postgres决定使用PG12数据库进行扫描,不确定这是Aurora的怪癖还是我们正在使用的Postgres版本。
请注意,如果我单独查询字段,即如果不使用OR
,它将命中两个DB中所有查询的索引。只有当使用OR
时,PG 12 db福尔斯退到顺序扫描。
编辑:发现了一些额外的信息。此表在没有大量更新的情况下会导致大量读取,并且几乎没有删除,这基于PG 13 Changelog中的注解,可能是统计数据过时的原因,因此计划不准确:
允许插入,而不仅仅是更新和删除,在autovacuum中触发清理活动(Laurenz Albe,Darafei Praliaskouski)
1条答案
按热度按时间eimct9ow1#
这是一个糟糕的统计数据的问题。第一次执行认为几乎有40000行匹配
WHERE
条件,第二次执行知道它不超过1。收集统计数据
并弄清楚为什么自动统计数据收集是不够的。