--了解基本的索引结构后--
索引扫描的几种类型
1.索引唯一扫描
2.索引范围扫描
3.索引全扫描
4.索引跳跃扫描
5.索引快速扫描
索引条目时按顺序存储的而表中的数据时随机存储的
索引的聚簇因子向优化器表明了具有同样索引值的行是不是存放在同一个或连续的一系列数据块中,
或者是否被分散存放在表的多个数据块中
look
索引聚簇因子(t1.t2表数据来源见
http://blog.itpub.net/26477854/viewspace-1072535/)
t1表的数据是连续插入100个0,100个1。。。100个99
t2表的数据是0~99顺序插入后继续0~99,插100遍
zo_leave@orcl> select t1.table_name || '.' || t1.index_name a,
2 t1.clustering_factor b, --索引聚簇因子
3 t2.blocks,
4 t2.num_rows
5 from user_indexes t1, all_tables t2
6 where t1.table_name = t2.table_name
7 and t1.table_name in ('T1', 'T2');
A B BLOCKS NUM_ROWS
--------------- ---------- ---------- ----------
T2.T2_INDEX1 10000 152 10000
T1.T1_INDEX1 154 152 10000
已用时间: 00: 00: 00.04
很明显的看到,由于t1表的数据插入方式,建立在t1表上的索引将会有较低的聚簇因子
从而优化器会在查询t1表时选择索引扫描而在查询表t2时选用全表扫描。
--聚簇因子是帮助优化器作出决定的关键信息
***深入研究可选:
索引的聚簇因子的大致计算方式
1.索引唯一扫描(index unique scan)
当谓语中包含使用唯一索引或主键索引的列作为条件的时候就会选择index unique scan
这种类型的索引能够保证对于某个特定的值只能返回一行数据。
索引结果被从根到叶子进行遍历直到某个条目取出行编号,再使用行编号来访问包含这一行的表数据块
look
创建示范表
create table del_test as select * from dba_users
并修改user_id字段为主键
zo_leave@orcl> set autot traceo
zo_leave@orcl> select * from del_test where user_id = 50;
已用时间: 00: 00: 00.04
执行计划
----------------------------------------------------------
Plan hash value: 1427567532
--------------------------------------------------------------------------------
----------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |
--------------------------------------------------------------------------------
----------
| 0 | SELECT STATEMENT | | 1 | 2170 | 1 (0)|
00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| DEL_TEST | 1 | 2170 | 1 (0)|
00:00:01 |
|* 2 |
INDEX UNIQUE SCAN | PK_DELTEST | 1 | | 0 (0)|
00:00:01 |
--------------------------------------------------------------------------------
----------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("USER_ID"=50)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
1259 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
2.索引范围扫描(index range scan)
在谓语中包含将会返回一定范围数据的条件时就会选择索引范围扫描,索引可以是唯一的也可以是不唯一的,因为由该条件来确定
是否会返回多个数据行的。因此,所指定条件可以用<,>,like,between,=,当然这个范围越大,索引扫描的范围也会越大,越有可能
由索引全表扫描来接替索引范围扫描。
look (继续查询del_test表,还是熟悉的语句,但是不是原来的味道了)
zo_leave@orcl> select * from del_test where user_id >= 50;
已选择19行。
已用时间: 00: 00: 00.03
执行计划
----------------------------------------------------------
Plan hash value: 1669476646
--------------------------------------------------------------------------------
----------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |
--------------------------------------------------------------------------------
----------
| 0 | SELECT STATEMENT | | 19 | 41230 | 2 (0)|
00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| DEL_TEST | 19 | 41230 | 2 (0)|
00:00:01 |
|* 2 |
INDEX RANGE SCAN | PK_DELTEST | 19 | | 1 (0)|
00:00:01 |
--------------------------------------------------------------------------------
----------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("USER_ID">=50)
Note
-----
- dynamic sampling used for this statement
统计信息
----------------------------------------------------------
9 recursive calls
0 db block gets
12 consistent gets
0 physical reads
0 redo size
3545 bytes sent via SQL*Net to client
427 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
19 rows processed
--未完待续
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26477854/viewspace-1073601/
,如需转载,请注明出处,否则将追究法律责任。