唯一性索引(Unique Index)与普通索引(Normal Index)差异(下)

声明:本篇知识体系受到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编号1,block编号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工具。

 

 

2、Unique 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=12,unique index长度为len=11。差异就是在于0x06的第二列col[1]标志位。

 

 

3、结论

 

唯一索引和普通索引在结构上存在差异,主要表现在存储结构和方式上。两者相比,唯一索引在体积上略小一点。但是从实际应用方面,唯一索引只是比普通索引增加了列值约束。其他如执行计划、效率没有过多的差别。

 

 

此时笔者想法有两个以为:

 

首先,Oracle在设计唯一索引的时候,为什么要选择这样的结构?在使用的时候有什么优势所在?

 

其次,唯一索引没有选择隐式的约束,这种结构类型如何实现唯一的效果?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值