postgresql Postgres:为什么索引没有被查询?

olqngx59  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(178)

我有两个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)

eimct9ow

eimct9ow1#

这是一个糟糕的统计数据的问题。第一次执行认为几乎有40000行匹配WHERE条件,第二次执行知道它不超过1。
收集统计数据

ANALYZE table1;

并弄清楚为什么自动统计数据收集是不够的。

相关问题