索引扫描探究



本次研究的是常用的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索引跳跃扫描。
适用于多列索引。当条件列处于一个多列索引中。并且不是首列。这样就会触发索引条扫描

标签: 暂无标签
oraask2

写了 49 篇文章,拥有财富 561,被 72 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2012-9-13 13:01:44
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
回复

使用道具

P4 | 发表于 2013-8-12 21:11:02
顶一下。。。。。。。。。。。。
回复

使用道具

P5 | 发表于 2013-8-13 07:46:07
看一下。。。。。。。。。。。。
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈