本次研究的是常用的B-TREE索引。
数据准备:
CREATE TABLE AS
SELECT *
FROM USER_OBJECTS
alter table MY_OBJECTS
add constraint PK_MY_OBJECTS primary key (OBJECT_ID)
using index
现在实验开始:
1索引唯一性扫描
这种扫描常见于在联机交易系统。当一个表有主键的时候我们知道一条记录的键值,我们就可以通过这种扫描得到该条记录的信息。这种索引扫描的特性就是当数据库找到一条记录的时候就不用再寻找其他的纪录。因为这条记录是唯一的。
其实在B-TREE中是不允许有非唯一值存在的。如果有两个相同的值,B-TREE是没有办法存储的。在叶子节点中放在那里呢?如何排序呢。所以,对于非唯一性索引,Oracle会按犍值和ROWID存储。而唯一性索引只要按键值存储就可以了。
SELECT *
FROM MY_OBJECTS
WHERE OBJECT_ID = 20
执行计划如下:
SELECT STATEMENT, GOAL = ALL_ROWS 2 1 88
TABLE ACCESS BY INDEX ROWIDCOMMON MY_OBJECTS 2 1 88
INDEX UNIQUE SCAN COMMON PK_MY_OBJECTS1 1
2索引范围扫描。
顾名思义,就是知道值的范围来扫描索引,得到纪录的信息。
SELECT *
FROM MY_OBJECTS
WHERE OBJECT_ID between 1 and 20
SELECT STATEMENT, GOAL = ALL_ROWS 3 9 792
TABLE ACCESS BY INDEX ROWIDCOMMON MY_OBJECTS 3 9 792
INDEXRANGESCAN COMMON PK_MY_OBJECTS2 9
特别需要注意的是使用LIKE (*)%这种情况也适用索引范围扫描。LIKE (*)%的含义就是查找(*)开头的键值。
3索引全扫描。
实际的动作可能与其名称不相符。其动作如下,从根部查找所以起始的叶子块。(一只向左下寻找),然后通过叶子块中的链表连接到之后的块。一次读取一块。顺序读取。这种读取的结果免去了排序。
select object_id
from My_Objects
order by object_id
SELECT STATEMENT, GOAL = ALL_ROWS 156 22911 160377
SORT ORDER BY 156 22911 160377
TABLE ACCESS FULL COMMON MY_OBJECTS 71 22911 160377
object_id就是索引列上的值。如果我们去掉子句order by object_id就是下面这种扫描方式了。
4索引快速全扫描
select object_id
from My_Objects
SELECT STATEMENT, GOAL = ALL_ROWS 13 22911 114555
INDEX FAST FULL SCANCOMMON PK_MY_OBJECTS13 22911 114555
它读取所有块,包括分枝块。采用多块读取。不按顺序检索数据。
5索引跳跃扫描。
适用于多列索引。当条件列处于一个多列索引中。并且不是首列。这样就会触发索引条扫描
|
|