【问题标题】:Postgres: index on multiple column with different leading columnPostgres:具有不同前导列的多列索引
【发布时间】:2017-12-21 06:47:01
【问题描述】:

我有两列的两个索引:

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"?

【问题讨论】:

  • 使用explain (analyze, buffers, timing)查看更多细节并找出差异
  • 谢谢,我刚刚添加了缓冲区和计时结果。

标签: postgresql indexing postgresql-performance


【解决方案1】:

你是对的,计划是一样的。

执行时间的差异只是巧合。或许更多的索引被第二次缓存了。

重复EXPLAIN 几次以获得统计相关的结果。

【讨论】:

  • 没有差异...只有一个结果。
  • 我说的是执行时间的差异。正如您所怀疑的那样,读取的缓冲区会有所不同。
猜你喜欢
  • 2021-01-19
  • 2017-09-08
  • 2021-02-22
  • 2020-05-24
  • 2014-04-14
相关资源
最近更新 更多