问题描述
我有一个查询,它在filter
子句之后有几个WHERE
条件。
此外,大多数涉及的列上都有索引。
当我运行EXPLAIN命令时,我看到:
-> Bitmap Index Scan on feature_expr_idx (cost=0.00..8.10 rows=14 width=0)
feature_expr_idx
是WHERE
子句中一列的索引。
Filter: ((NOT is_deleted) AND (vehicle_type = 'car'::text) AND (source_type = 'NONE'::text))
为什么只在结果中显示一个索引,而其他也具有索引的列却是过滤器的一部分?
解决方法
Postgresql具有一个聪明的引擎,该引擎尝试计划运行查询的最佳方法。通常,这涉及从磁盘读取尽可能少的内容,因为磁盘操作很慢。索引如此有用的原因之一是,通过读取索引,我们可以找到表中需要读取的少量行才能满足查询要求,因此我们可以避免读取整个表。但是请注意,索引也位于磁盘上,因此读取索引也需要一些时间。
现在,假设您的查询有两个过滤器,一个位于A列上方,另一个位于B列上方,这两个索引都已建立索引。根据postgresql收集的统计数据,大约有5行满足A列上的过滤器,约1000行满足B列上的过滤器。在这种情况下,只读取A列上的索引是有意义的,然后读取所有匹配的5(左右)行,并过滤掉与B列上的过滤器不匹配的任何行。读取B列上的索引可能比仅读取5行更昂贵!
实际原因可能与我的示例不同,但关键是postgresql只是试图尽可能地提高效率。