2012-09-04 87 views
5

我正在测试不同的查询,我很好奇数据库如何决定使用位图堆扫描和索引扫描。如何确定位图堆扫描和索引扫描?

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

正如你可以看到有一个客户表(dellstore的例子),我添加一个索引到电子邮件列。

首先查询是在这里:

SELECT * FROM客户那里电子邮件像 '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 

其他查询是在这里:

SELECT * FROM客户那里电子邮件像“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 

你能解释一下这个例子,为什么Bitmap和索引扫描用在这里?

谢谢..

+1

查看@ araqnid的答案和这个:http ://wiki.postgresql.org/images/4/45/Explaining_EXPLAIN.pdf 寻找'索引扫描'。关键可能是'优化器可以选择它[位图扫描]用于低选择性的任何可索引扫描“ – dezso

+1

我认为这个问题很适合dba.SE。 –

回答

6

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

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

一个问题是投影表中的多少行将被访问只是一个估计。但是,正如你可以想象的那样,'IT%'很可能比'ITQ%'匹配得多(请记住,后缀不是索引扫描的一部分,只有最后一个过滤器)

+0

总行数:20.000 - 通过索引扫描找到的行:5 - 通过位图找到的行:6 – TraviJuu