我有两列两列索引:
create index idx_film_length_rating on film (length, rating);
create index idx_film_rating_length on film (rating, length);
执行时:
explain analyze select title, length, rating, replacement_cost, rental_rate
from film
where rating = 'G' and length between 60 and 70
postgres认为idx_film_rating_length始终是最佳选择,并使用此索引。但是为什么如果没有第二个索引,idx_film_rating_length,查询会变慢?根据我的理解,执行计划是相同的,提取块是相同的,它们应该是相同的。
只有一个索引的结果是:
"Bitmap Heap Scan on film (cost=4.44..35.70 rows=13 width=34) (actual time=0.102..0.120 rows=18 loops=1)"
" Recheck Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
" Heap Blocks: exact=14"
" -> Bitmap Index Scan on idx_film_rating_length (cost=0.00..4.44 rows=13 width=0) (actual time=0.095..0.095 rows=18 loops=1)"
" Index Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
"Planning time: 0.316 ms"
"Execution time: 0.160 ms"
结果表中有两个索引:
"Bitmap Heap Scan on film (cost=4.44..35.70 rows=13 width=34) (actual time=0.030..0.041 rows=18 loops=1)"
" Recheck Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
" Heap Blocks: exact=14"
" -> Bitmap Index Scan on idx_film_rating_length (cost=0.00..4.44 rows=13 width=0) (actual time=0.024..0.024 rows=18 loops=1)"
" Index Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
"Planning time: 0.199 ms"
"Execution time: 0.065 ms"
你可以看到计划是相同的,第二个更快。
====================================== 由@a_horse_with_no_name推荐 添加缓冲区和详细信息后:
"Bitmap Heap Scan on film (cost=4.44..35.70 rows=13 width=34) (actual time=0.692..0.716 rows=18 loops=1)"
" Recheck Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
" Heap Blocks: exact=14"
" Buffers: shared hit=14 read=2"
" -> Bitmap Index Scan on idx_film_cover (cost=0.00..4.44 rows=13 width=0) (actual time=0.680..0.680 rows=18 loops=1)"
" Index Cond: ((rating = 'G'::mpaa_rating) AND (length >= 60) AND (length <= 70))"
" Buffers: shared read=2"
"Planning time: 1.773 ms"
"Execution time: 1.441 ms"
似乎问题可能与: “缓冲区:共享命中= 14读取= 2”?
答案 0 :(得分:0)
你是对的,计划是一样的。
执行时间的差异只是巧合。也许更多的索引是第二次缓存。
多次重复Clubhouse: .... times
Fibre Ready: .... times
以获得统计相关的结果。