【发布时间】:2021-01-19 14:57:51
【问题描述】:
我很好奇多列索引的前导列的概念。
我正在使用这个示例dvdrental db。
这是查询:
SELECT
title,
length,
rating,
replacement_cost,
rental_rate
FROM film
WHERE length BETWEEN 60 AND 70
AND rating = 'G';
我有两个正在使用的索引:
#1
CREATE INDEX IF NOT EXISTS film_idx_length_rating
ON film(length, rating);
#2
CREATE INDEX IF NOT EXISTS film_idx_rating_length
ON film(rating, length);
在创建两个索引后,使用规划器选择的索引进行规划:
QUERY PLAN
Bitmap Heap Scan on film (cost=4.47..39.34 rows=15 width=34) (actual time=0.020..0.033 rows=18 loops=1)
Recheck Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))
Heap Blocks: exact=14
-> Bitmap Index Scan on film_idx_rating_length (cost=0.00..4.46 rows=15 width=0) (actual time=0.015..0.015 rows=18 loops=1)
Index Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))
Planning Time: 0.202 ms
Execution Time: 0.065 ms
在执行了查询计划EXPLAIN ANALYZE 之后,规划器选择了第二个查询,但是来自两个索引的查询计划实际上并没有任何显着差异,只有规划器选择的索引。
这是为什么?为什么当rating 用作前导列时,它会被选中而不是length 作为前导列?
来自docs 有这个:
多列 B 树索引可用于涉及索引列的任何子集的查询条件,但当前导(最左侧)列存在约束时,索引效率最高。确切的规则是,前导列上的等式约束,加上没有等式约束的第一列上的任何不等式约束,将用于限制扫描的索引部分。
但我不是很明白,也许有人可以给我一个例子?
谢谢!
【问题讨论】:
-
是的,已编辑后
标签: postgresql