g: ------, lock: 0, len=12
...............................................................
.......
选取这一行为例:
row#0[8020] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 02
col 1; len 6; (6): 01 00 1b ab 00 01
col 0 表示第一列,长度为2,c1 02表示是多少呢?
SQL> select * from tt where rownum<4 order by id;
ID NAME
---------- --------------------
1 wO
2 wang
6 hong
SQL> select dump(1,16) from dual;
DUMP(1,16)
----------------------------------
Typ=2 Len=2: c1,2 ==>这里是c1 02,0省略了
这下清楚了吧,第一行第一列存储的是1,orale存储数据的方法很复杂。
col 1表示的是第二列,长度是6, 01 00 1b ab 00 01就是索引的值,是十六进制数,我们可以转化为二进制数:
00000001 00000000 00011011 10101011 00000000 00000001
-----------------------------------------------------------------------------------------------------------------------------------------------------------
00000001 00 ==>1x2x2=4 前10位表示了数据文件号
000000 00011011 10101011 ==>4096+2048+512+256+128+32+8+2+1=7083 这里的22位表示了块号
00000000 00000001==>1 16位代表着行号
此时排序并查rowid:
此时用第一列的rowid,
通过oracle提供的一个包,可以求出对象编号,文件号,块号:
执行如下图:
上面从索引存储的段以及数据段进行分析。
我们知道索引不一定会提高查询效率,往往乱建索引会严重影响查询效率,系统用不用索引,我们不能干预(但是dba可以手动改变),是oracle CBO选择的结果。
下面我们可以做一个小实验:
SQL> select count(rowid) from t;
COUNT(ROWID)
------------
4718644
SQL> select count(rowid) from t where id=1;
COUNT(ROWID)
------------
4718592
SQL> select count(rowid) from t where id=2;
COUNT(ROWID)
------------
26
SQL> select count(rowid) from t where id=3;
COUNT(ROWID)
------------
26
SQL> set autotrace traceonly;
SQL> select * from tt;
执行计划
----------------------------------------------------------
Plan hash value: 264906180
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3556K| 67M| 1742 (2)| 00:00:21 |
| 1 | TABLE ACCESS FULL| TT | 3556K| 67M| 1742 (2)| 00:00:21 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
此时是全表扫描读取,是多块读取,,这样读取比较快,如果此时用索引,则效率会低。
SQL> select * from tt where id=5;
执行计划
----------------------------------------------------------
Plan hash value: 3103123359
--------------------------------------------------------------------------------
-------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
e |
--------------------------------------------------------------------------------
-------
| 0 | SELECT STATEMENT | | 5 | 100 | 4 (0)| 00:
00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TT | 5 | 100 | 4 (0)| 00:
00:01 |
|* 2 | INDEX RANGE SCAN | INDEX_T | 5 | | 3 (0)| 00:
00:01 |
--------------------------------------------------------------------------------
-------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=5)
Note
-----
- dynamic sampling used for this statement (level=2)
此时是索引读取。
SQL> select * from tt where id=1;
执行计划
----------------------------------------------------------
Plan hash value: 264906180
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Byt