【发布时间】:2021-08-26 20:14:48
【问题描述】:
my_table 包括:
user_id | character varying | | not null |
epic_id | text | | not null |
"IDX_user" UNIQUE, btree ("user_id") WHERE status < 101
"IDX_epic" UNIQUE, btree ("epic_id") WHERE status < 101
有问题的查询
EXPLAIN ANALYZE SELECT * FROM my_table WHERE "epic_id" = 'asdf' and "status" < 101 LIMIT 1;
Limit (cost=0.28..8.29 rows=1 width=276) (actual time=0.230..0.231 rows=0 loops=1)
-> Index Scan using "IDX_user" on my_table (cost=0.28..8.29 rows=1 width=276) (actual time=0.229..0.230 rows=0 loops=1)
Filter: ("epic_id" = 'asdf'::text)
Rows Removed by Filter: 273
Planning Time: 0.122 ms
Execution Time: 0.248 ms
有一个非常好的IDX_epic。为什么我们要使用 IDX_user,遍历 100 行,并且在事务中使用它时可能会导致烦人的锁?
有趣的花絮
-
SET random_page_cost=1没有帮助,正如其他 stackoverflow 帖子所推荐的那样 - 在本地,它使用正确的索引!本地只有 90 行
status < 101 - 在执行
"epic_id" = table.random_column的内部连接时,计划确实使用IDX_epic。 -
"user_id"和"epic_id"是不同的类型,但据我所知,text和character varying之间的差异接近于 0。 - 根据
pg_stat_all_indexes,IDX_epic的idx_scan为 9,这证实它除了我的测试外没有被使用。
【问题讨论】:
-
你先运行
VACUUM ANALYZE了吗? -
您最近是否对生产表进行过分析(或真空分析)?
-
终于修好了,谢谢>。
标签: postgresql indexing