为何PostgreSQL在复合索引场景下选择顺序扫描而非位图索引扫描?
问题解答
这核心是复合B-tree索引的左前缀匹配规则在起作用,PostgreSQL的查询优化器会根据索引结构和查询成本选择最优执行计划:
对于第一个索引
idx_orders_table_order_id_customer_id,它的排序逻辑是先按order_id排列,在同一个order_id下再按customer_id排序。这种结构下,所有customer_id = 'VINET'的记录分散在不同order_id分组里,数据库要找到这些记录得遍历整个索引的所有分组去筛选,这个操作的成本甚至比直接全表扫描(Seq Scan)还高。优化器算下来全表扫描更划算,自然就不会用这个索引。而第二个索引
idx_orders_table_customer_id_order_id是先按customer_id排序,同一个customer_id下再按order_id排序。此时所有customer_id = 'VINET'的记录在索引里是连续存放的,数据库可以快速定位到这个连续区间,然后用Bitmap Index Scan——这种扫描方式适合匹配行数中等的场景,能把随机IO转化为顺序IO,比全表扫描高效得多,所以优化器会选择这个索引。
你提到的低基数列倾向于位图扫描是对的,但前提是索引能被有效利用。第一个索引因为列顺序问题根本没法被高效利用,优化器自然不会考虑用它来做任何索引扫描,包括位图扫描。
内容的提问来源于stack exchange,提问作者DumbCoder
相关产品推荐
相关产品推荐

