我正在测试不同的查询,我很好奇数据库如何决定使用位图堆扫描和索引扫描。
在客户上创建索引customers_email_idx(电子邮件 varchar_pattern_ops);
正如您所看到的那样,有一个customers表(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'等电子邮件;的 - &GT;询问 使用位图堆扫描
解释分析查询在这里:
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和Index Scan吗?
谢谢..
答案 0 :(得分:8)
表中总共有多少行?该决定基于索引扫描将输出的行的比例。
如果要访问足够高比例的表,则使用位图索引扫描来确保尽可能多的磁盘访问是顺序的。相比之下,普通索引扫描会对表数据进行一次一页的随机访问。 (如果预计要访问的表的比例足够高,则根本不使用索引,并且顺序加载整个表数据)
一个问题是,要从表中访问多少行的投影只是估计值。但是你可以想象,'IT%'的匹配可能超过'ITQ%'(请记住,后缀不是索引扫描的一部分,只是最终的过滤器)