索引组织表定义和描述
索引组织表类似数据存储在B树索引结构中的变体的表。在堆表中,行是无序插入。在索引组织表中,行数据存储在表的主键定义的索引中。 B树中的每个索引条目还存储非关键列的值,因此,索引是数据,数据就是是索引。应用程序可以使用SQL语句熟练的操作索引组织表。
下图说明了索引组织表和普通堆表的区别,这里简单说明一下
堆表 | 索引组织表 |
---|---|
通过rowid标识一行 | 通过主键标识一行 |
可以通过rowid访问行 | 通过主键访问行 |
在一些排序情况下是全表扫描的模式返回结果 | 在一些排序情况下全索引扫描返回所需的行 |
可以与其他表一起存储在table cluster | 不能存储在table cluster |
可以包含LONG数据类型的列和LOB数据类型的列 | 可以包含LOB类型的列,不能包含LONG类型的列 |
可以包含虚拟列 | 不能包含虚拟列 |
下图说明了按索引组织的一张部门表的结构。叶子块包含表的行,按主键顺序排序。例如,第一个叶子块中的第一个值显示部门ID为20,部门名称Marketing,经理ID为201,地点ID为1800。
索引组织的表以相同的结构存储所有数据,不需要存储rowid。如图3-3所示,索引组织表中的叶子块1包含以下条目,这些条目按主键排序:
20,Marketing,201,1800
30,Purchasing,114,1700
索引组织表中的叶子块2包含以下条目:
50,Shipping,121,1500
60,IT,103,1400
按主键顺序扫描索引组织的表行将按以下顺序读取块:
- block 1
- block 2
为了将堆组织表中的数据访问与索引组织表中的数据访问进行对比,假设堆组织的部门表中块1包含以下行:
50,Shipping,121,1500
20,Marketing,201,1800
块2包含以下行:
30,Purchasing,114,1700
60,IT,103,1400
此堆表的B树索引叶子块包含以下条目,其中第一个值为主键,第二个为rowid:
20,AAAPeXAAFAAAAAyAAD
30,AAAPeXAAFAAAAAyAAA
50,AAAPeXAAFAAAAAyAAC
60,AAAPeXAAFAAAAAyAAB
按主键顺序扫描表行将按以下顺序读取表段块:
-
Block 1
-
Block 2
-
Block 1
-
Block 2
因此,此示例中的块I/O数量是索引组织示例中的I/O数量的两倍。
带有行溢出的索引组织表
创建索引组织表时,可以将单独的段指定为行溢出区。在按索引组织的表中,B树索引条目可能很大,因为它们包含一整行,因此包含条目的单独段非常有用。相反,B树条目通常很小,因为它们由键和行标识符组成。
如果指定了行溢出区域,则数据库可以将索引组织表中的行划分为以下部分:
- 索引条目
此部分包含所有主键列的列值,指向行的溢出部分的物理rowid以及一些非关键的列。这部分存储在索引段中。 - 溢出部分
此部分包含其余非关键列的列值。该部分存储在溢出存储区段中。
索引组织表上的二级索引
二级索引是索引组织表上的索引。从某种意义上说,它是索引的索引。二级索引是一个独立的架构对象,与索引组织的表分开存储。
如“rowid数据类型”中所述,Oracle数据库对索引组织的表使用称为逻辑rowid的行标识符。逻辑rowid是表主键的base64编码表示形式。逻辑行标识符的长度取决于主键的长度。
索引叶块中的行由于插入而可以在块内或块之间移动。索引组织的表中的行不会像堆组织的行那样迁移。由于索引组织表中的行没有永久的物理地址,因此数据库使用基于主键的逻辑行ID。
例如,假设Departments表是索引组织的。 location_id列存储每个部门的ID。该表存储以下行,最后一个值作为地点ID:
10,Administration,200,1700
20,Marketing,201,1800
30,Purchasing,114,1700
40,Human Resources,203,2400
location_id列上的辅助索引可能具有如下索引条目,其中逗号后面的值是逻辑行ID:
1700,*BAFAJqoCwR/+
1700,*BAFAJqoCwQv+
1800,*BAFAJqoCwRX+
2400,*BAFAJqoCwSn+
二级索引使用既不是主键也不是主键前缀的列提供对索引组织表的快速有效的访问。例如,查询ID大于1700的部门名称可以使用二级索引来加快数据访问速度。
1. 逻辑rowid和物理猜测
二级索引使用逻辑rowid定位表行。逻辑rowid包括物理猜测,物理猜测是指首次创建索引条目时的物理rowid。 Oracle数据库可以使用物理猜测直接探测索引组织表的叶块,而绕过主键搜索。当行的物理位置发生变化时,,即使它包含的物理猜测是旧的,逻辑rowid仍然有效。
对于堆表,二级索引的访问包含一个二级索引的扫描和一个额外的I / O,以获取包含行的数据块。对于索引组织表,根据物理猜测的用途和准确性,二级索引的访问有所不同:
- 无需物理猜测,访问包含两次索引扫描:主键索引扫描之后紧接着二级索引扫描。
- 没有物理猜测,访问依赖他们的准确性
- 通过准确的物理猜测,访问包括二级索引扫描和一个额外I / O,获取包含行的数据块。
- 对于不准确的物理猜测,访问包括二级索引扫描和一个I / O,获取到错误的数据块(如猜测所指示),紧接着是通过主键值在索引组织表上进行唯一索引扫描。
2.索引组织表上的位图索引
索引组织表上的二级索引可以是位图索引。如“位图索引”中所述,位图索引为每个索引键存储一个位图。
当位图索引存在于索引组织的表上时,所有位图索引都使用堆组织的映射表。映射表存储索引组织表的逻辑rowid。每个映射表的行为该索引组织表的行存储一个逻辑rowid。
数据库使用搜索键访问位图索引。如果数据库找到了key,则位图条目将转换为一个物理rowid。对于堆表,数据库使用物理rowid访问基表。对于索引组织的表,数据库使用物理rowid访问映射表,这里又产生一个逻辑rowid,数据库将使用该逻辑rowid访问索引组织的表。图3-4说明了对department_iot索引组织表一个带有索引的查询。
上图描述了一个来自Departments_iot的位置id为1800的查询语句。数字1800指向一个索引映射表。1800与映射表中的物理rowid相关联。该rowid指向映射表中的逻辑行。然后逻辑rowid指向索引组织表中的行(30,Marketing,210,1800)。
经过上面的介绍,我们总结一下索引组织表的优点:
1.数据和索引合二为一,减少了IO次数,效率更高
2.但是对于频繁的DML不适合,因为要频繁的移动数据,索引叶子节点的数据要频繁移动,会影响效率。
3.如果是根据主键进行唯一查询或者范围查询,效率会更高,因为索引组织表中,叶子节点存放的都是具体数据,而且是经过排序存放的,所以扫描块的时候,可以挨着扫描,减少了离散IO。