唯一性索引(Unique Index)與普通索引(Normal Index)差異(中)
宣告:本篇知識方法受到dbsnake相關文章啟發,特此感謝!
在本系列的前篇(http://space.itpub.net/17203031/viewspace-700089)裡,我們探討了唯一索引和普通索引在應用角度上的差異。實驗中,我們發現在基礎資料相同的情況下,兩型別索引在體積上有細微的差異,這使得我們可以猜測兩種型別索引在儲存結構上的可能差異。
本篇打算從儲存結構入手,探討兩種型別索引的差異。
1、 環境準備
同前篇相同,準備相同的資料索引列取值,建立不同型別的索引。為了減少整理資料量,所以選擇較小的資料集。
SQL> select * from v$version where rownum<2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
SQL> create table t (id number, vid number);
Table created
SQL> select * from t;
ID VID
---------- ----------
1 1
2 2
3 3
//建立普通索引
SQL> create index idx_t_normalid on t(id);
Index created
//建立唯一性索引
SQL> create unique index idx_t_uniqueid on t(vid);
Index created
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed
SQL> col object_name for a20;
SQL> select object_name, object_id from dba_objects where object_name in ('IDX_T_NORMALID','IDX_T_UNIQUEID');
OBJECT_NAME OBJECT_ID
-------------------- ----------
IDX_T_NORMALID 75141
IDX_T_UNIQUEID 75142
2、 普通索引邏輯結構分析
思路是從索引樹入手,現將索引段結構Dump出去,檢查整體分佈情況。
//獲取跟蹤檔案位置
SQL> select name, value from v$diag_info where name='Default Trace File';
NAME VALUE
------------------------------ --------------------------------------------------------------------------------
Default Trace File /u01/diag/rdbms/wilson/wilson/trace/wilson_ora_5850.trc
//將索引樹Dump出到Trace檔案
SQL> alter session set events 'immediate trace name treedump level 75141';
Session altered
注意:v$diag_info檢視是Oracle 11g中新推出的檢視型別,其中包括了所有診斷檔案的位置和目錄。其中Default Trace File專案就是當前會話對應的Trace File路徑和名稱,不需要我們過去那樣使用自定義函式查詢。
此時,我們檢索Trace File內容,核心片段如下:
*** 2011-06-15 01:47:04.350
*** SESSION ID:(20.13) 2011-06-15 01:47:04.350
*** CLIENT ID:() 2011-06-15 01:47:04.350
*** SERVICE NAME:(wilson) 2011-06-15 01:47:04.350
*** MODULE NAME:(PL/SQL Developer) 2011-06-15 01:47:04.350
*** ACTION NAME:(Command Window - New) 2011-06-15 01:47:04.350
----- begin tree dump
leaf: 0x415af1 4283121 (0: nrow: 3 rrow: 3)
----- end tree dump
上面的Tree Dump結果,說明因為索引很小(只有三行記錄),只有一個索引塊中包括資料。其中葉子節點為3個,該索引塊的地址為(0x415af1,十進位制表示為4283121)。
索引塊4283121對應的實際檔案和資料塊資訊是什麼呢?使用dbms_utiliy包的相關方法,可以幫助獲取到對應檔案和塊號。
SQL> select dbms_utility.data_block_address_file(4283121), dbms_utility. data_block_address_block(4283121) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------ ------------------------------
1 88817
索引塊在檔案1,對應塊號為88817。
使用邏輯dump出塊的結構資訊。
SQL> alter system dump datafile 1 block 88817;
System altered
DUMP在跟蹤檔案上的核心內容為:
--核心片段
Block dump from cache:
Dump of buffer cache at level 4 for tsn=0, rdba=4283121
BH (0x2dff3578) file#: 1 rdba: 0x00415af1 (1/88817) class: 1 ba: 0x2dea0000
Block header dump: 0x00415af1
Object id on Block? Y
seg/obj: 0x12585 csc: 0x00.396f48 itc: 2 flg: - typ: 2 - INDEX
fsl: 0 fnx: 0x0 ver: 0x01
row#0[8020] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 41 5a e9 00 00
row#1[8008] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 03
col 1; len 6; (6): 00 41 5a e9 00 01
row#2[7996] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 04
col 1; len 6; (6): 00 41 5a e9 00 02
----- end of leaf block dump -----
End dump data blocks tsn: 0 file#: 1 minblk 88817 maxblk 88817
實際Dump出的資訊很多,篇幅原因,筆者只是將最核心的部分加以展現。
首先關注最後的三個row#資訊,該部分表示三個葉子節點的核心內容。其中[]中包括的是葉子節點在索引塊中的相對偏移量。Len表示該葉子所佔用空間長度是多少(注意:此處的Normal Index葉子節點佔用12長度)。
最後,觀察行與行之間的偏移量差(7996-8008-8020),正好是行間的距離12位。
每個葉子節點包括兩個column內容,分別佔據2位和6位。由於是使用16進位制形式儲存,我們不能直接看出內容含義。下面實驗可以幫助我們進行猜測:
--關鍵資料演算:
SQL> select dump(1,1016) from dual;
DUMP(1,1016)
-----------------
Typ=2 Len=2: c1,2
SQL> select dump(2,1016) from dual;
DUMP(2,1016)
-----------------
Typ=2 Len=2: c1,3
SQL> select dump(3,1016) from dual;
DUMP(3,1016)
-----------------
Typ=2 Len=2: c1,4
我們的索引列取值就是1、2、3、4,上面使用DUMP函式的結果,告訴我們跟蹤檔案中每個row的第一列表示的是索引列取值。索引葉子節點內容無非就是rowid和索引鍵值。那麼row的第二列含義必然可能就是rowid相關內容。
只對第三行資料進行試算:
16進製取值:00 41 5a e9 00 02
2進製取值:00000000 01000001 01011010 11101001 00000000 00000010
根據相關資料,我們進行如下設定:
File_ID:前10位:00000000 01=1
Block_id 中間22位:000001 01011010 11101001=88809
Slot_id:00000000 00000010=2
如果改值是rowid,那麼一定和資料表T行的rowid存在對應關係。
SQL> select t.*,t.rowid, dbms_rowid.rowid_relative_fno(t.rowid) fno, dbms_rowid.rowid_block_number(t.rowid)
blockn,dbms_rowid.rowid_row_number(t.rowid) rown from t;
ID VID ROWID FNO BLOCKN ROWN
---------- ---------- ------------------ ---------- ---------- ----------
1 1 AAASWCAABAAAVrpAAA 1 88809 0
2 2 AAASWCAABAAAVrpAAB 1 88809 1
3 3 AAASWCAABAAAVrpAAC 1 88809 2
Rowid中包括的資訊:檔案編號+物件編號+塊編號+塊內slot編號;索引葉子中的第二列資料,已經能夠提供檔案編號、塊編號和內部slot編號。物件編號是進行選取Select時候就帶入的。
3、普通索引物理結構分析
從上面的邏輯結構,我們看到了儲存的邏輯結構。下面根據資訊,我們到物理儲存層面看普通索引結構。注意,此處我們只關注一行資料,就是row2[7996]的葉子節點。
我們現在有該索引的檔案編號和塊編號,缺乏就是實際的偏移量。下面首先計算出實際的偏移量。
SQL> select file_name, tablespace_name from dba_data_files where file_id=1;
FILE_NAME TABLESPACE_NAME
-------------------------------------------------------------------------------- ------------------------------
/u01/oradata/WILSON/datafile/o1_mf_system_6bcsnqfc_.dbf SYSTEM
SQL> select tablespace_name,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces where tablespace_name='SYSTEM';
TABLESPACE_NAME SEGMENT_SPACE_MANAGEMENT
------------------------------ ------------------------
SYSTEM MANUAL
資料表索引對應的表空間SYSTEM,是使用MSSM進行Segment Space Management。所以,計算出的偏移量就是:
7996+68+(2-1)*24=8088
下面使用BBED工具直接進行塊讀取,注意,首先需要關閉資料庫。
==將dump筷
[oracle@oracle11g test]$ bbed parfile=par.txt
Password:
BBED: Release 2.0.0.0.0 - Limited Production on Wed Jun 15 02:05:20 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> info
File# Name Size(blks)
----- ---- ----------
1 /u01/oradata/WILSON/datafile/o1_mf_system_6bcsnqfc_.dbf 106240
(篇幅原因,有省略……)
//定位到指定的檔案和塊位置(也可以使用set file 1 block 88817)
BBED> set dba 0x00415af1
DBA 0x00415af1 (4283121 1,88817)
//定位塊內的偏移量
BBED> set offset 8088
OFFSET 8088
//DUMP顯示出來
BBED> dump
File: /u01/oradata/WILSON/datafile/o1_mf_system_6bcsnqfc_.dbf (1)
Block: 88817 Offsets: 8088 to 8191 Dba:0x00415af1
------------------------------------------------------------------------
000002c1 04060041 5ae90002 000002c1 03060041 5ae90001 000002c1 02060041
5ae90000 0d000040 15000002 00401500 000203c2 085eac00 01150015 00004015
00000100 40150000 0103c208 5aac0001 11001100 0040110f 00090040 110f0009
03c20858 0106496f
<32 bytes per line>
再看一下我們將row2匯出的資訊:
row#2[7996] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 04
col 1; len 6; (6): 00 41 5a e9 00 02
注意:兩個標記0x02和0x06的作用是標記列Column資訊,用於分割。
4、 區域性結論
對普通索引結構來說,索引葉子節點上儲存索引鍵值和對應資料行rowid。兩者是以行中不同column的方式進行儲存,鍵值在前,rowid在後。
下面我們使用相同的流程處理Unique Index,檢查相關的儲存結構。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-700163/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 唯一性索引(Unique Index)與普通索引(Normal Index)差異(上)索引IndexORM
- 唯一性索引(Unique Index)與普通索引(Normal Index)差異(下)索引IndexORM
- Unique Index和Normal Index差異經典對比IndexORM
- 再說Unique Index和Normal Index行為差異IndexORM
- 索引唯一性掃描(INDEX UNIQUE SCAN)索引Index
- Elasticsearch之索引模板index template與索引別名index aliasElasticsearch索引Index
- index索引Index索引
- oracle dml與索引index(一)Oracle索引Index
- 主鍵(PK)與非空唯一索引(Unique Index)的區別索引Index
- 分割槽索引之本地(local index)索引和全域性索引(global index)索引Index
- mysql索引型別:FULLTEXT、NORMAL、SPATIAL、UNIQUEMySql索引型別ORM
- Mysql——index(索引)使用MySqlIndex索引
- oracle index索引原理OracleIndex索引
- mysql 索引( mysql index )MySql索引Index
- 點陣圖索引(Bitmap Index)——索引共用索引Index
- 【INDEX】Postgresql索引介紹IndexSQL索引
- pandas(3):索引Index/MultiIndex索引Index
- create index , rebuild index troubleshooting 索引故障解決IndexRebuild索引
- 分割槽索引(Partition Index)與SQL執行計劃(中)索引IndexSQL
- pk 、unique index 和 index 區別Index
- Oracle中的虛擬列索引-nosegment indexOracle索引Index
- 分析index降低索引層次Index索引
- index merge合併索引Index索引
- Oracle索引分裂(Index Block Split)Oracle索引IndexBloC
- 索引優化index skip scan索引優化Index
- Oracle筆記 之 索引(index)Oracle筆記索引Index
- oracle index索引結構(一)OracleIndex索引
- ElasticSearch 倒排索引(Inverted Index)| 什麼是倒排索引?Elasticsearch索引Index
- 【INDEX】使用“alter index ××× monitoring usage;”語句監控索引使用與否Index索引
- INDEX UNIQUE SCAN,INDEX FULL SCAN和INDEX FAST FULL SCANIndexAST
- Index Unique Scan (213)Index
- oracle全文索引之STOPLIST_ CTXCAT 索引_INDEX SETOracle索引Index
- oracle 點陣圖索引(bitmap index)Oracle索引Index
- 點陣圖索引:原理(BitMap index)索引Index
- zt_如何加速索引index建立索引Index
- 使用Index提示 強制使用索引Index索引
- 點陣圖索引(bitmap-index)索引Index
- 平衡樹索引(b-tree index)索引Index