您的位置:首页 > 其它

几种索引扫描方式学习

2014-08-12 12:33 302 查看
1:索引唯一扫描(index unique scan)

通过唯一索引查找一个数值经常返回单个 ROWID。

create table t1 as select * from dba_objects;

exec dbms_stats.gather_table_stats(YALI,'T1')

create unique index t1_id on t1(ibject_id); -----唯一索引

select * from t1 where object_id=5;

Execution Plan

----------------------------------------------------------

Plan hash value: 472361049

-------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 207 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 207 | 2 (0)| 00:00:01 |

|* 2 | INDEX UNIQUE SCAN | T1_ID | 1 | | 1 (0)| 00:00:01 |

-------------------------------------------------------------------------------------

2:索引范围扫描(index range scan)

(a) 在唯一索引列上使用了 range 操作符(> < <> >= <= between)。

(b) 在唯一组合索引上,只使用部分列进行查询(引导列需要存在),如组合索引列全存在index unique scan。

(c) 对非唯一索引列上进行的任何查询。

(a) select * from t1 where object_id <5; ----在唯一索引列上使用了 range 操作符(> < <> >= <= between)。

Execution Plan

----------------------------------------------------------

Plan hash value: 2288890262

-------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 3 | 621 | 3 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 3 | 621 | 3 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | T1_ID | 3 | | 2 (0)| 00:00:01 |

-------------------------------------------------------------------------------------

(b) 对于唯一的组合索引

drop index t1_id;

create unique index idx_t1 on t1(owner,object_type,object_id);

select * from t1 where OBJECT_TYPE='INDEX' AND OWNER='SCOTT';

Execution Plan

----------------------------------------------------------

Plan hash value: 50753647

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 2 | 414 | 3 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 414 | 3 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | IDX_T1 | 2 | | 2 (0)| 00:00:01 |

--------------------------------------------------------------------------------------

引导列存在,但是查询索引部分列,INDEX RANGE SCAN。

select * from t1 where OBJECT_ID=5 AND OBJECT_TYPE='INDEX' AND OWNER='SCOTT';

Execution Plan

----------------------------------------------------------

Plan hash value: 3983389365

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 207 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 207 | 2 (0)| 00:00:01 |

|* 2 | INDEX UNIQUE SCAN | IDX_T1 | 1 | | 1 (0)| 00:00:01 |

--------------------------------------------------------------------------------------

谓词中查询所有组合索引的列, INDEX UNIQUE SCAN。

3:索引全扫描(index full scan)

与全表扫描对应,也有相应的全 Oracle 索引扫描。在某些情况下,可能进行全 Oracle 索引扫描而不是范围扫描,需要注意的是全 Oracle 索引扫描只在 CBO模式下才有效。 CBO 根据统计数值得知进行全 Oracle 索引扫描比进行全表扫描更有效时,才进行全 Oracle 索引扫描,而且此时查询出的数据都必须从索引中可以直接得到。

create index idx_id on t1(object_id);

SELECT MAX(OBJECT_id) from t1;

Execution Plan

----------------------------------------------------------

Plan hash value: 1123511277

-------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

-------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | 5 | | |

| 2 | INDEX FULL SCAN (MIN/MAX)| IDX_ID | 1 | 5 | 2 (0)| 00:00:01 |

-------------------------------------------------------------------------------------

索引全扫描INDEX FULL SCAN

4:索引快速扫描(index fast full scan)

扫描索引中的所有的数据块,与 index full scan 很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。 在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间,其他索引都采取单块读。

可以参考/article/1666852.html

组合索引,返回列都在索引中,返回相对结果多。

select count(object_id) from t1;

Execution Plan

----------------------------------------------------------

Plan hash value: 2929617283

--------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 5 | 41 (0)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | 5 | | |

| 2 | INDEX FAST FULL SCAN| IDX_ID | 65441 | 319K| 41 (0)| 00:00:01 |

--------------------------------------------------------------------------------

索引快速全扫描INDEX FAST FULL SCAN

create index idx_ooo on t1(owner,object_name,object_type);

select owner,object_name,object_type from t1 where object_type='INDEX';

2594 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 4139004340

--------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 2618 | 102K| 127 (0)| 00:00:02 |

|* 1 | INDEX FAST FULL SCAN| IDX_OOO | 2618 | 102K| 127 (0)| 00:00:02 |

--------------------------------------------------------------------------------

索引快速全扫描INDEX FAST FULL SCAN (组合索引,查询列都在索引中,返回结果比较多)

select * from t1 where object_type='INDEX';

2594 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 3617692013

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 2618 | 250K| 262 (1)| 00:00:04 |

|* 1 | TABLE ACCESS FULL| T1 | 2618 | 250K| 262 (1)| 00:00:04 |

--------------------------------------------------------------------------

组合索引,查询列不都在索引中

5:索引跳跃扫描(INDEX SKIP SCAN)

可以参考http://www.itpub.net/thread-1372696-1-1.html 很受启发

复合索引上,如果 SQL 中谓词条件只包含索引中的部分列,并且这些列不是建立索引时的第一列时,并且返回条数很少,就可能发生INDEX SKIP SCAN。这里 SKIP 的意思是因为查询条件没有第一列或前面几列,被忽略了。

如果有引导列会走 索引范围扫描(index range scan)

select * from t1 where object_name='EMP';

Execution Plan

----------------------------------------------------------

Plan hash value: 2431949587

---------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 2 | 196 | 23 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 2 | 196 | 23 (0)| 00:00:01 |

|* 2 | INDEX SKIP SCAN | IDX_OOO | 2 | | 21 (0)| 00:00:01 |

---------------------------------------------------------------------------------------

索引跳跃扫描 INDEX SKIP SCAN --(组合索引,谓词中没有引导列,返回条数很少)

select * from t1 where owner='YALI';

7 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 1128734305

---------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 6 | 588 | 8 (0)| 00:00:01 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 6 | 588 | 8 (0)| 00:00:01 |

|* 2 | INDEX RANGE SCAN | IDX_OOO | 6 | | 3 (0)| 00:00:01 |

---------------------------------------------------------------------------------------

索引范围扫描 INDEX RANGE SCAN (组合索引,谓词中引导列,返回条数很少)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: