唯一性索引(Unique Index)與普通索引(Normal Index)差異(下)

realkid4發表於2011-06-18

 

宣告:本篇知識體系受到dbsnake相關文章啟發,特此感謝!

 

本系列的中篇(http://space.itpub.net/17203031/viewspace-700163)中,我們進行了Normal Index的匯出和結構分析。分析後,我們發現Normal Index葉子節點實際上是表現為兩個column結構,第一列為索引列值,第二列為對應rowid。本篇中,我們以相同的方法對unique index進行研究。

 

1、  Unique Index邏輯結構Dump

 

相似,使用Treedump的方法,將索引樹idx_t_uniqueid進行匯出。

 

 

--Unique Index

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_6330.trc

 

//75142為索引idx_t_uniqueidobject_id

SQL> alter session set events 'immediate trace name treedump level 75142';

Session altered

 

//Trace File中的核心片段如下:

*** 2011-06-15 02:16:41.584

*** SESSION ID:(138.4) 2011-06-15 02:16:41.584

*** CLIENT ID:() 2011-06-15 02:16:41.584

*** SERVICE NAME:(wilson) 2011-06-15 02:16:41.584

*** MODULE NAME:(PL/SQL Developer) 2011-06-15 02:16:41.584

*** ACTION NAME:(Command Window - New) 2011-06-15 02:16:41.584

 

----- begin tree dump

leaf: 0x415af9 4283129 (0: nrow: 3 rrow: 3)

----- end tree dump

 

 

由於該索引結構很小,只包括一個葉子節點索引塊。該塊地址的十六進為:0x415af9,對應十進位制地址為4283129。查詢對應的file編號和block編號。

 

 

SQL> select dbms_utility.data_block_address_file(4283129), dbms_utility. data_block_address_block(4283129)  from dual;

 

DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES

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

                             1                          88825

 

 

地址4283129對應的位置為file編號1block編號88825

 

使用資料塊dump的方法,將資料塊dump出。

 

 

SQL> alter system dump datafile 1 block 88825;

System altered

 

//Trace File中的內容

Start dump data blocks tsn: 0 file#:1 minblk 88825 maxblk 88825

Block dump from cache:

Dump of buffer cache at level 4 for tsn=0, rdba=4283129

BH (0x2afeef14) file#: 1 rdba: 0x00415af9 (1/88825) class: 1 ba: 0x2adf6000

  set: 5 pool 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 55,19

 

(篇幅原因,省略部分……

 

Block header dump:  0x00415af9

 Object id on Block? Y

 seg/obj: 0x12586  csc: 0x00.396f56  itc: 2  flg: -  typ: 2 - INDEX

     fsl: 0  fnx: 0x0 ver: 0x01

 

row#0[8021] flag: ------, lock: 0, len=11, data:(6):  00 41 5a e9 00 00

col 0; len 2; (2):  c1 02

row#1[8010] flag: ------, lock: 0, len=11, data:(6):  00 41 5a e9 00 01

col 0; len 2; (2):  c1 03

row#2[7999] flag: ------, lock: 0, len=11, data:(6):  00 41 5a e9 00 02

col 0; len 2; (2):  c1 04

----- end of leaf block dump -----

End dump data blocks tsn: 0 file#: 1 minblk 88825 maxblk 88825

 

 

此處,我們看到了Unique Index索引葉子節點和Normal Index的差異。在Unique Index葉子節點上,每行row只對應了一個col資訊(而非normal index的兩個)。Col[0]中對應的是索引列的鍵值。而rowid被放置在了行row的頭部。這點差異就意味著兩種索引結構在儲存構成上的確有一些差距。

 

下面,我們來檢查一下純物理結構,藉助BBED工具。

 

 

2Unique Index物理結構分析

 

至此,我們已經知道了索引葉子塊所在檔案和塊編號,進行物理分析只需要計算額外的offset偏移量。

 

從對unique index索引塊dump出的結果看,我們可以看到相對偏移量資訊。

 

row#2[7999] flag: ------, lock: 0, len=11, data:(6):  00 41 5a e9 00 02

col 0; len 2; (2):  c1 04

----- end of leaf block dump -----

 

與對Normal Index相同,我們研究第三行資料,相對偏移量是7999。由於索引idx_t_uniqueid也存在在system表空間,屬於MSSM管理方式。計算塊內偏移量資訊:

 

 

7999+68+(2-1)*24=8091

 

 

 

使用BBED的要素已經獲取到,進行物理分析。

 

//設定檔案和塊號

BBED> set dba 0x00415af9

        DBA             0x00415af9 (4283129 1,88825)

 

//設定偏移量

BBED> set offset 8091

        OFFSET          8091

 

BBED> dump

 File: /u01/oradata/WILSON/datafile/o1_mf_system_6bcsnqfc_.dbf (1)

 Block: 88825            Offsets: 8091 to 8191           Dba:0x00415af9

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

 00000041 5ae90002 02c10400 0000415a e9000102 c1030000 00415ae9 000002c1

 02100000 40110e00 02004011 0e000203 c20837ac 00011300 13000040 110e0001

 0040110e 000103c2 0834ac00 01060006 00004011 0d000700 40110d00 0703c208

 32010657 6f

 

 <32 bytes per line>

 

 

對應原有的dump結果,可以清晰看到索引列鍵值和rowid資訊。

 

 

row#2[7999] flag: ------, lock: 0, len=11, data:(6):  00 41 5a e9 00 02

col 0; len 2; (2):  c1 04

----- end of leaf block dump ---

 

 

 

加上連帶的四個0,可以看到儲存的方式。Rowid在行頭,以0x02開頭的col[0]結構,儲存索引列鍵值。對比原有的normal index結構,可以發現差距。為便於檢視,normal index的結構如下:

 

 

//Normal Index葉子節點,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>

 

Normal Index葉子節點長度為len=12unique index長度為len=11。差異就是在於0x06的第二列col[1]標誌位。

 

 

3、結論

 

唯一索引和普通索引在結構上存在差異,主要表現在儲存結構和方式上。兩者相比,唯一索引在體積上略小一點。但是從實際應用方面,唯一索引只是比普通索引增加了列值約束。其他如執行計劃、效率沒有過多的差別。

 

 

此時筆者想法有兩個以為:

 

首先,Oracle在設計唯一索引的時候,為什麼要選擇這樣的結構?在使用的時候有什麼優勢所在?

 

其次,唯一索引沒有選擇隱式的約束,這種結構型別如何實現唯一的效果?

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-700187/,如需轉載,請註明出處,否則將追究法律責任。

相關文章