问题:btree和位图索引之间有什么区别? 我需要了解btree和位图索引之间的结构差异,然后了解在字段上使用b树与位图索引之间的区别。
答:在内部,位图和btree索引有很大的不同,但是在功能上它们是相同的,因为它们用于帮助Oracle以比全表扫描更快的速度检索行。B树索引和位图索引之间的基本区别包括:
- 语法差异:位图索引包含“ bitmap”关键字。btree索引不显示“位图”。
- 基数差异:位图索引通常适用于具有大量重复值(低基数)的列,而b树索引最适合于高基数列。
- 内部结构差异:内部结构差异很大。b树索引具有索引节点(基于数据块大小),它是树形式:
位图索引如下所示,这是一个具有零和一个(位)值的二维数组:
B树索引
Oracle索引中最古老和最受欢迎的类型是标准B树索引,该索引擅长为简单查询提供服务。B树索引是在Oracle的早期版本中引入的,并在Oracle中广泛使用。B树索引用于避免大型排序操作。例如,要求按排序顺序显示10,000行的SQL查询通常会使用B树索引,以避免在查询时还需要占用临时空间进行数据排序。
使用默认的B树结构创建索引时,Oracle提供了多个选项。它允许您在多个列(连接的索引)上建立索引,以提高访问速度。而且,它允许各个列以不同的顺序排序。例如,我们可以在一个名为last_name的列上按升序创建B树索引,并在索引内有第二列,以降序显示薪水列。
create index name_salary_idx on person (last_name asc,salary desc); |
虽然B树索引非常适合简单查询,但在以下情况下它们并不是很好:
- 低基数列:具有小于200个枚举值的列,在使用标准B树索引时,带来的收益不大。
- 不支持SQL函数:在SQL查询时,B树索引无法使用Oracle的内置函数。Oracle提供了多种内置函数,允许SQL语句查询索引列的某一部分,或查询索引列的转换结果,但建立的如果不是函数索引,则针对字段的索引在有函数(除max, min之外)引用时,索引将失效。
在引入基于Oracle函数的索引(FBI)之前,由于这些缺点,基于Oracle成本的SQL优化器必须执行耗时的全表扫描。因此,Oracle引入更强大的索引结构类型也就不足为奇了。
位图索引
Oracle位图索引与标准B树索引非常不同。在位图结构中,将创建一个二维数组,其中索引表中的每一行都有一列。每列代表位图索引中的不同值。此二维数组表示索引中的每个值乘以表中的行数。在行检索时,Oracle将位图解压缩到RAM数据缓冲区中,以便可以对其进行快速扫描以查找匹配的值。这些匹配值以行ID列表的形式传递给Oracle,并且这些行ID值可以直接访问所需的信息。
当一个表包含多个位图索引时,位图索引的真正好处就出现了。每个单独的列可能具有低基数。多个位图索引的创建提供了一种非常强大的方法,可以快速回答复杂的SQL查询。
例如,假设有一个具有许多低基数列的汽车数据库,例如car_color,car_make,car_model和car_year。每列本身包含少于100个不同的值,而B树索引在2000万辆汽车的数据库中将毫无用处。但是,在查询中将这些索引组合在一起,可以提供比起读取基本表中的2000万行中的每一行的传统方法快得多的响应时间。例如,假设我们想找到1981年生产的旧蓝色丰田卡罗拉。
Select license_plat_nbr from vehicle and make = \’toyota\’ and year = 1981; |
Oracle使用一种称为位图索引合并的特殊优化器方法来为该查询提供服务。在位图索引合并中,每个Row-ID或RID列表都是通过使用位图独立构建的,并且使用特殊的合并例程来比较RID列表并找到相交的值。使用这种方法,Oracle在处理多个低基数列时可以提供亚秒级的响应时间。