为什么PostgreSQL不先按PK查找(当`WHERE`在PK上包含一个条件时,也在其他列上)?

sc4hvdpw  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(110)

当我对我的PostgreSQL数据库运行以下查询时(其中courses表上的id列是主键,is_deleted上还有一个索引,它是一个布尔值):

SET enable_seqscan = OFF;

EXPLAIN ANALYZE SELECT c.title
FROM courses AS c
WHERE c.id = 1 AND NOT (c.is_deleted)
LIMIT 1

字符串
这是查询计划:

Limit  (cost=4.15..6.17 rows=1 width=318) (actual time=0.035..0.036 rows=1 loops=1)
  ->  Bitmap Heap Scan on courses c  (cost=4.15..6.17 rows=1 width=318) (actual time=0.033..0.034 rows=1 loops=1)
        Filter: ((NOT is_deleted) AND (id = 1))
        Rows Removed by Filter: 2
        Heap Blocks: exact=2
        ->  Bitmap Index Scan on ix_courses_is_deleted  (cost=0.00..4.14 rows=2 width=0) (actual time=0.017..0.017 rows=6 loops=1)
              Index Cond: (is_deleted = false)
Planning Time: 0.179 ms
Execution Time: 0.068 ms


除非我误解了这一点(这是完全可能的,因为我对这个完全陌生),它基本上是通过is_deleted FIRST进行过滤,而不是简单地使用PK及其索引进行查找。这没有意义,如果它简单地执行Index Scan using pk_courses on courses,不是更有效吗?!

pxy2qtax

pxy2qtax1#

PostgreSQL估计在is_deleted上使用索引与使用主键索引的效率差不多,在这种情况下,它更喜欢使用较小的索引。
但这个问题是学术性的。因为你必须禁用顺序扫描才能让PostgreSQL使用索引,很可能是因为表很小,PostgreSQL认为索引扫描在这种情况下效率很低。就像你不会查阅目录来从床上方的书架上的五本书中挑选一本一样。

相关问题