当我对我的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
,不是更有效吗?!
1条答案
按热度按时间pxy2qtax1#
PostgreSQL估计在
is_deleted
上使用索引与使用主键索引的效率差不多,在这种情况下,它更喜欢使用较小的索引。但这个问题是学术性的。因为你必须禁用顺序扫描才能让PostgreSQL使用索引,很可能是因为表很小,PostgreSQL认为索引扫描在这种情况下效率很低。就像你不会查阅目录来从床上方的书架上的五本书中挑选一本一样。