索引扫描研究

来源:互联网 发布:什么是移动数据 编辑:程序博客网 时间:2024/06/08 04:50
 
 
本次研究的是常用的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               耗费=115     基数=43662     字节=567606     IO 耗费=113
INDEX FULL SCAN     对象所有者=SYS     对象名称=INDX     耗费=115     基数=43662     字节=567606     IO 耗费=113
 
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索引跳跃扫描。
适用于多列索引。当条件列处于一个多列索引中。并且不是首列。这样就会触发索引条扫描

原创粉丝点击