如何找到某个键值在索引中存在于哪个BLOCK中

比如我想知道我的EMAIL在测试系统中存在了什么位置,那就需要DUMP BLOCK来查看了,可是索引不像数据,数据的话我只要知道ROWID,然后根据ROWID得到数据存在于哪个数据文件的哪个块中,然后直接DUMP这个BLOCK就可以了。可是索引存了ROWID,但是你却SELECT不出来,下面来演示下怎么找到一个值在索引中存在于什么地方[@more@]

首先得到索引的OBJECT_ID,然后DUMP出这个索引的根信息:
SQL> select DATA_OBJECT_ID,OBJECT_ID from dba_objects where object_name='IDX_MEMBERIDENTITY_IDCONTENT';

DATA_OBJECT_ID OBJECT_ID
-------------- ----------
130792 130792
然后DUMP这个索引树
SQL> alter session set events 'immediate trace name treedump level 130792';

Session altered

然后找到DUMP出来的TRACE文件,内容大致如下:
----- begin tree dump
branch: 0x8465e8d 138829453 (0: nrow: 240, level: 2)
branch: 0x8466296 138830486 (-1: nrow: 353, level: 1)
leaf: 0x8465e8e 138829454 (-1: nrow: 224 rrow: 223)
leaf: 0x8465e8f 138829455 (0: nrow: 195 rrow: 195)
leaf: 0x8465e90 138829456 (1: nrow: 197 rrow: 197)
说明这个索引是两层的,后面的NROW和RROW分别表示这个块可以存放多少行数据以及目前存放了多少行数据,从上面可以看到索引的根节点的地址是138829453,那么可以通过下面的方式得到这个根节点存在于哪个BLOCK中:
SQL> SELECT DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(138829453) "file",
2 DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(138829453) "block"
3 FROM DUAL;

file block
---------- ----------
33 417421
然后把33号文件的417421号BLOCK DUMP出来,就可以看到根节点中的内容:
SQL> alter system dump datafile 33 block 417421;

System altered
然后把EMAIL:zhang41082@163.com转换成16进制,去根TRACE文件中的值进行对比,就可以发现EMAIL值是存在于哪个叶节点下面的,首先转换EMAIL到16进制:
SQL> select utl_raw.cast_to_raw('zhang41082@163.com') from dual;

UTL_RAW.CAST_TO_RAW('ZHANG4108
--------------------------------------------------------------------------------
7A68616E673431303832403136332E636F6D

因为索引中存的16进制都是小写的,而且每个字符中间是有空格的,所以格式化后的EMAIL的16进制为:
7a 68 61 6e 67 34 31 30 38 32 40 31 36 33 2e 63 6f 6d

根据这个字符串到刚才DUMP出来的根节点去对比,可以找到下面一段:
row#227[6288] dba: 139652795=0x852eebb
col 0; len 4; (4): 79 7a 67 30
col 1; TERM
row#228[6493] dba: 138917985=0x847b861
col 0; len 9; (9): 7a 65 6e 67 79 61 6e 67 61
col 1; TERM
row#229[5114] dba: 140549035=0x8609bab
col 0; len 8; (8): 7a 68 61 6e 67 67 68 32

可以看到EMAIL转换后的16进制是在上面这两个值中间的,那说明EMAIL是存放在139652795叶节点下面的,那下面就来找到这个叶节点并把它DUMP出来:
SQL> SELECT DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(138917985) "file",
2 DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(138917985) "block"
3 FROM DUAL;

file block
---------- ----------
33 505953
SQL> alter system dump datafile 33 block 505953;

System altered
在叶节点DUMP出来的TRACE文件中可以找到下面的地方:
row#291[6494] dba: 138917683=0x847b733
col 0; len 9; (9): 7a 68 61 6e 67 34 31 30 33
col 1; TERM
row#292[6509] dba: 138917684=0x847b734
col 0; len 16; (16): 7a 68 61 6e 67 34 34 31 36 35 35 36 32 34 36 40
这说明最后的EMAIL是在索引中的位置是存放在138917683对应的BLOCK中的,接下来把这个BLOCK DUMP出来:
SQL> SELECT DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(138917683) "file",
2 DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(138917683) "block"
3 FROM DUAL;

file block
---------- ----------
33 505651
SQL> alter system dump datafile 33 block 505651;

System altered
最后可以在DUMP出来的BLOCK中找到下面内容:
row#5[1104] flag: ------, lock: 0, len=32
col 0; len 18; (18): 7a 68 61 6e 67 34 31 30 38 32 40 31 36 33 2e 63 6f 6d
col 1; len 10; (10): 00 01 f6 3b 09 87 52 5b 00 28
这个地方就是EMAIL在这个索引中真正存在的内容,其中COL0表示的是EMAIL的16进制,然后COL1表示的是这个EMAIL对应的ROWID,至于这个ROWID怎么还原成真正的ROWID,那下次在来完成吧。

另外,这里只是一个简单的索引,那么如果是分区索引、压缩索引或者复合索引、函数索引等等,情况可能会略有差别

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25016/viewspace-1020075/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25016/viewspace-1020075/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值