Leaf block dump
===============
header address 47520285706852=0x2b382dbfca64
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 2
kdxcofbo 40=0x28
kdxcofeo 950=0x3b6
kdxcoavs 910
kdxlespl 0
kdxlende 0
kdxlenxt 20971653=0x1400085
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8032
row#0[4492] flag: ------, lock: 0, len=3540
col 0; len 2; (2): c1 02
col 1; len 6; (6): 01 00 03 43 00 00
col 2; len 6; (6): 01 00 03 7c 00 3f
col 3; len 3519; (3519):
cf 49 92 24 49 92 24 49 92 cf 24 49 92 24 49 92 24 49 cf 92 24 49 92 24 49
.....
49 92 24 49 92 24 49 92 02 ff 1e 49 92 24 49 92 24 49 92
row#1[950] flag: ------, lock: 0, len=3542
col 0; len 2; (2): c1 02
col 1; len 6; (6): 01 00 03 7c 00 40
col 2; len 6; (6): 01 00 06 36 00 7f
col 3; len 3521; (3521):
cf 24 49 92 24 49 92 24 49 cf 92 24 49 92 24 49 92 24 cf 49 92 24 49 92 24
.....
92 02 ff 1e 49 92 24 49 92 24 49 92 cf 24 49 92 24 49 92 24 49
由于在位图索引中每一个键值被压缩为键值+ROWID范围+位图键的方式,这里对于row#0
可以看到
col 0; len 2; (2): c1 02为键值
col 1; len 6; (6): 01 00 03 43 00 00
col 2; len 6; (6): 01 00 03 7c 00 3f
为ROWID的范围
col 3; len 3519 就是他的位图键,由于位图键非常长,我们主要取出
cf 49 92 24 49 92 24 49 92
这个片段进行分析
首先cf应该是一个标示位(作用未知)
剩下的
49 92 24 49 92 24 49 92 我们进行分析,实际上这里每一个FF代表了一个字节,一个字节8位FF代表是的11111111
SQL> select to_number('49','xxxxxxxxxxxxxx') from dual;
TO_NUMBER('49','XXXXXXXXXXXXXX
------------------------------
73
SQL> select to_number('92','xxxxxxxxxxxxxx') from dual;
TO_NUMBER('92','XXXXXXXXXXXXXX
------------------------------
146
SQL> select to_number('24','xxxxxxxxxxxxxx') from dual;
TO_NUMBER('24','XXXXXXXXXXXXXX
------------------------------
36
实际上他们的十进制为73 146 36 73 146 36 73 146
我们转换为2进制然后进行取反同时不足不满8位的如下:
10010010(73) 01001001(146) 00100100(36) 10010010(73) 01001001(146) 00100100(36) 10010010(73) 01001001(146)
那么组合下来如下:
1001001001001001001001001001001001001001001001001001001001001001
其中每一个位图BIT代表一个ROWID他们是连续的,根据起始方位ROWID是能推算出来的。
这样可以清晰的看到表中字段1的取值(实际上c1 02=1)位图如上,他们是交替出现和我表中数据一样如下:
SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_row_number(rowid),TESTt_bi2.* from TESTT_BI2 where dbms_rowid.rowid_block_number(rowid)=835;
DBMS_ROWID.ROWID_BLOCK_NUMBER( DBMS_ROWID.ROWID_ROW_NUMBER(RO NAME ID
------------------------------ ------------------------------ -------------------- -----------
835 0 gaopeng 1
835 1 gaopeng 2
835 2 gaopeng 3
835 3 gaopeng 1
835 4 gaopeng 2
835 5 gaopeng 3
835 6 gaopeng 1
835 7 gaopeng 2
835 8 gaopeng 3
835 9 gaopeng 1
835 10 gaopeng 2
835 11 gaopeng 3
835 12 gaopeng 1
835 13 gaopeng 2
835 14 gaopeng 3
835 15 gaopeng 1
835 16 gaopeng 2
835 17 gaopeng 3
..........
这段如果理解一下就是
如果SELECT * FROM TEABLE WHERE ID=1
那么这时候位图中取值为1的都是满足条件的,将会被取出(根据ROWID)