9

我正在测试不同的查询,我很好奇 db 如何决定使用 Bitmap Heap Scan 和 Index Scan。

在客户上创建索引customers_email_idx(电子邮件varchar_pattern_ops);

如您所见,有一个客户表(dellstore 示例),我在电子邮件列中添加了一个索引。

第一个查询在这里:

从电子邮件中选择 *,例如“ITQ%@dell.com”;-> 使用索引扫描查询

解释分析查询在这里:

                                                           QUERY PLAN                                                            
---------------------------------------------------------------------------------------------------------------------------------
 Index Scan using customers_email_idx on customers  (cost=0.00..8.27 rows=2 width=268) (actual time=0.046..0.046 rows=0 loops=1)
   Index Cond: (((email)::text ~>=~ 'ITQ'::text) AND ((email)::text ~<~ 'ITR'::text))
   Filter: ((email)::text ~~ 'ITQ%@dell.com
 '::text)
 Total runtime: 0.113 ms

其他查询在这里:

从电子邮件中选择 *,例如“IT%@dell.com”;-> 使用位图堆扫描查询

解释分析查询在这里:

                                                          QUERY PLAN                                                          
------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on customers  (cost=4.54..106.77 rows=2 width=268) (actual time=0.206..0.206 rows=0 loops=1)
   Filter: ((email)::text ~~ 'IT%@dell.com
 '::text)
   ->  Bitmap Index Scan on customers_email_idx  (cost=0.00..4.54 rows=29 width=0) (actual time=0.084..0.084 rows=28 loops=1)
         Index Cond: (((email)::text ~>=~ 'IT'::text) AND ((email)::text ~<~ 'IU'::text))
 Total runtime: 0.273 ms

你能解释一下为什么在这里使用位图和索引扫描这个例子吗?

谢谢..

4

1 回答 1

8

表中总共有多少行?该决定基于索引扫描将输出的行的比例。

如果要访问足够高比例的表,则使用位图索引扫描来确保尽可能多的磁盘访问是顺序的。相比之下,普通索引扫描对表数据进行一次一页的随机访问。(并且如果预计要访问的表的比例足够高,则根本不使用索引,并且顺序加载整个表数据)

一个问题是,表中将要访问多少行的预测只是一个估计值。但正如您可以想象的那样,'IT%' 可能比 'ITQ%' 匹配更多(请记住,后缀不是索引扫描的一部分,只是最终过滤器)

于 2012-09-04T10:35:32.550 回答