【发布时间】:2021-05-23 23:30:05
【问题描述】:
我有下表:
create table images
(
image_id bigint,
image text,
url text,
post_id bigint,
checksum text,
path varchar
);
create index images_postid_idx
on images (post_id);
create index image_2020_idx
on images (image);
(是的,没有主键!还有一些其他字段大多为空且与查询无关。)
这个非常简单的查询:
SELECT 1 FROM images where image = 'foo';
产生以下执行计划:
Gather (cost=1000.00..40080349.00 rows=93 width=4) (actual time=339826.750..339933.048 rows=0 loops=1)
Workers Planned: 10
Workers Launched: 10
Buffers: shared hit=527195 read=39504582 dirtied=23
-> Parallel Seq Scan on images (cost=0.00..40079339.70 rows=9 width=4) (actual time=339800.607..339800.607 rows=0 loops=11)
Filter: (image = 'foo'::text)
Rows Removed by Filter: 3459138
Buffers: shared hit=527195 read=39504582 dirtied=23
Planning Time: 3.684 ms
JIT:
Functions: 34
" Options: Inlining true, Optimization true, Expressions true, Deforming true"
" Timing: Generation 4.039 ms, Inlining 382.076 ms, Optimization 121.531 ms, Emission 71.917 ms, Total 579.563 ms"
Execution Time: 339978.002 ms
导致该问题的原因可能是什么?我复制了表格,放置了相同的索引并复制了几千行 => 那里一切正常。我还运行了ANALYSE images 来更新统计数据。
我不确定为什么规划器不使用此表上的索引。在总共 380,000,000 行中,image 有 28,091,491 个不同的值。由于我的查询实际上没有从表中选择任何内容,为什么规划器会选择除索引扫描以外的其他内容?
我正在使用 PG 12.5。
更新:
select * from pg_stats where tablename = 'images' and attname = 'image';的输出:https://pastebin.com/Xeg7DjQd
更新 2:
\d+ images的输出:
Table "public.images"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------------+-------------------+-----------+----------+---------+----------+--------------+-------------
image_id | bigint | | | | plain | |
image | text | | | | extended | |
url | text | | | | extended | |
post_id | bigint | | | | plain | |
checksum | text | | | | extended | |
path | character varying | | | | extended | |
field1 | numeric | | | | main | |
field2 | numeric | | | | main | |
field3 | integer | | | | plain | |
field4 | numeric | | | | main | |
field5 | double precision | | | | plain | |
field6 | double precision | | | | plain | |
Indexes:
"image_2020_idx" btree (image)
"images_postid_idx" btree (post_id)
Replica Identity: FULL
Access method: heap
【问题讨论】:
-
可能索引处于无效状态。尝试
reindex重建它。 -
@Dai:不,不使用 Postgres。
text或varchar(n)之间的速度或存储要求绝对没有区别(如果两者都存储相同的字符串) -
@user1068464: no 255 不是 varchar 长度的幻数。
-
@steve 不,条件非常有选择性,PostgreSQL 绝对应该使用索引。
psql中\d images的输出是什么? -
没有主键的表没有意义。在尝试优化之前修复您的数据模型(图像、url 或路径的基数是什么?它们是否依赖于 image_id 和/或 post_id?
标签: postgresql indexing