關於ORACLE點陣圖索引內部淺論
我們都知道ORACLE點陣圖索引適用於欄位不同值很少的情況,同時修改DML會導致整個同樣的值
全部被鎖定,這嚴重影響了併發性,所以不建議OLTP系統大量使用點陣圖索引。
但是具體點陣圖索引的內部是如何排列和組織的呢?如下將進行探討,由於水平有限可能有一定錯誤。
首先認識BITMAP索引的組織方式,首先看一下ORACLE給出的這張圖
可以看到本圖中實際上有4種顏色藍色、綠色、紅色、黃色,BITMAP 索引也是B-TREE的格式,但是其頁節點儲存
的是鍵值+ROWID範圍+點陣圖鍵的方式,這樣一來可以很明顯的感知到BITMAP所以在鍵值很少的時候其空間比較B-TREE
索引是小很多的,而在點陣圖鍵方面使用一連串的0和1來表示是否存在相應的值,這樣一來ORACLE就能快速的進行是否有
值的定位。
接下來我們進行DUMP,先建立測試表
建立這樣一張表
SQL> select id,count(*) from testt_bit group by id;
ID COUNT(*)
----------- ----------
1 100000
2 100000
3 100000
同時在分佈上是連續的,1是1-100000行,2是100001-200000行,3是剩下的
在ID列上建立BIT MAP索引
create bitmap index TEST_BIT_IND on TESTT_BIT (ID)
首先進行BITMAP索引的結構DUMP如下:
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/ora11g/diag/rdbms/test/test/trace/test_ora_5604.trc
SQL> alter session set events 'immediate trace name treedump level 76306';
*** 2015-03-18 00:40:35.111
----- begin tree dump
branch: 0x1000333 16778035 (0: nrow: 8, level: 1)
leaf: 0x1000334 16778036 (-1: nrow: 2 rrow: 2)
leaf: 0x1000335 16778037 (0: nrow: 2 rrow: 2)
leaf: 0x1000336 16778038 (1: nrow: 2 rrow: 2)
leaf: 0x1000337 16778039 (2: nrow: 2 rrow: 2)
leaf: 0x1000338 16778040 (3: nrow: 2 rrow: 2)
leaf: 0x1000339 16778041 (4: nrow: 2 rrow: 2)
leaf: 0x100033a 16778042 (5: nrow: 2 rrow: 2)
leaf: 0x100033b 16778043 (6: nrow: 1 rrow: 1)
----- end tree dump
這裡清楚的看到了這個點陣圖索引的層次,首先它只有2層,1個根節點8個頁節點,每個葉節點包含2個索引條目(最後一個節點除外)
接下來我們DUMP根節點:
根據DBA(block adress)16778035進行換算
SQL> select dbms_utility.data_block_address_file(16778035),
2 dbms_utility.data_block_address_block(16778035) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------ ------------------------------
4 819
然後alter system dump datafile 4 block 819進行DUMP
header address 47810796042828=0x2b7bd183ba4c
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 7
kdxcofbo 42=0x2a
kdxcofeo 7972=0x1f24
kdxcoavs 7930
kdxbrlmc 16778036=0x1000334
kdxbrsno 0
kdxbrbksz 8056
kdxbr2urrc 0
關於這一部分引用一個文件(作者不詳)
其中的kdxcolev表示索引層級號,這裡由於我們轉儲的是根節點,所以其層級號為1。對葉子節點來說該值為0;
kdxcolok表示該索引上是否正在發生修改塊結構的事務;kdxcoopc表示內部操作程式碼;kdxconco表示索引條目中列的數量;
kdxcosdc表示索引結構發生變化的數量,當你修改表裡的某個索引鍵值時,該值增加;kdxconro表示當前索引節點中索引條目的數量,
但是注意,不包括kdxbrlmc指標;kdxcofbo表示當前索引節點中可用空間的起始點相對當前塊的位移量;
kdxcofeo表示當前索引節點中可用空間的最尾端的相對當前塊的位移量;kdxcoavs表示當前索引塊中的可用空間總量,
也就是用kdxcofeo減去kdxcofbo得到的。kdxbrlmc表示分支節點的地址,該分支節點存放了索引鍵值小於row#0(在轉儲文件後半部分顯示)
所含有的最小值的所有節點資訊;kdxbrsno表示最後一個被修改的索引條目號,這裡看到是0,表示該索引是新建的索引;
kdxbrbksz表示可用資料塊的空間大小。實際從這裡已經可以看到,即便是PCTFREE設定為0,也不能用足8192位元組。
row#0[8044] dba: 16778037=0x1000335
col 0; len 2; (2): c1 02
col 1; len 3; (3): 01 00 03
col 2; TERM
row#1[8031] dba: 16778038=0x1000336
col 0; len 2; (2): c1 02
col 1; len 4; (4): 01 00 03 f8
col 2; TERM
row#2[8019] dba: 16778039=0x1000337
col 0; len 2; (2): c1 03
col 1; len 3; (3): 01 00 04
col 2; TERM
row#3[8006] dba: 16778040=0x1000338
col 0; len 2; (2): c1 03
col 1; len 4; (4): 01 00 04 bf
col 2; TERM
row#4[7998] dba: 16778041=0x1000339
col 0; len 2; (2): c1 04
col 1; TERM
row#5[7985] dba: 16778042=0x100033a
col 0; len 2; (2): c1 04
col 1; len 4; (4): 01 00 05 57
col 2; TERM
row#6[7972] dba: 16778043=0x100033b
col 0; len 2; (2): c1 04
col 1; len 4; (4): 01 00 05 f8
col 2; TERM
這一部分是具體的關於各個葉節點的位置(起始位置的葉節點已經在kdxbrlmc 16778036=0x1000334給出)
其儲存方式為COL0 鍵值+COL1其對應的表中資料塊起始的DBA(可能包含BMB LEVEL1塊)
但是這裡
row#4[7998] dba: 16778041=0x1000339
col 0; len 2; (2): c1 04
col 1; TERM
並未包含實際的表的DBA,為什麼未知
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x01000130 Data dba: 0x01000133
Extent 1 : L1 dba: 0x01000130 Data dba: 0x01000138
Extent 2 : L1 dba: 0x01000140 Data dba: 0x01000141
Extent 3 : L1 dba: 0x01000140 Data dba: 0x01000148
Extent 4 : L1 dba: 0x01000150 Data dba: 0x01000151
Extent 5 : L1 dba: 0x01000150 Data dba: 0x01000158
Extent 6 : L1 dba: 0x01000160 Data dba: 0x01000161
Extent 7 : L1 dba: 0x01000160 Data dba: 0x01000168
Extent 8 : L1 dba: 0x01000170 Data dba: 0x01000171
Extent 9 : L1 dba: 0x01000170 Data dba: 0x01000178
Extent 10 : L1 dba: 0x01000300 Data dba: 0x01000301
Extent 11 : L1 dba: 0x01000300 Data dba: 0x01000308
Extent 12 : L1 dba: 0x01000310 Data dba: 0x01000311
Extent 13 : L1 dba: 0x01000310 Data dba: 0x01000318
Extent 14 : L1 dba: 0x01000320 Data dba: 0x01000321
Extent 15 : L1 dba: 0x01000320 Data dba: 0x01000328
Extent 16 : L1 dba: 0x01000380 Data dba: 0x01000382
Extent 17 : L1 dba: 0x01000400 Data dba: 0x01000402
Extent 18 : L1 dba: 0x01000480 Data dba: 0x01000482
Extent 19 : L1 dba: 0x01000500 Data dba: 0x01000502
Extent 20 : L1 dba: 0x01000580 Data dba: 0x01000582
比如:
row#2[8019] dba: 16778039=0x1000337
col 0; len 2; (2): c1 03
col 1; len 3; (3): 01 00 04
根據COL 1 01 00 04 實際是01000400,我們在BMB LEVEL3的dump中可以找到
Extent 17 : L1 dba: 0x01000400 Data dba: 0x01000402
實際上它是一個BMB LEVEL1塊,我們可以看他的資料塊實際上是0x01000402
可以進行DUMP這個資料塊是否是C1 03這個值
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/ora11g/diag/rdbms/test/test/trace/test_ora_6108.trc
SQL> alter system dump datafile 4 block 1026;
擷取第一行
tab 0, row 0, @0x1f89
tl: 15 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 8] 67 61 6f 70 65 6e 67 32
col 1: [ 2] c1 03
tab 0, row 1, @0x1f7a
可以看到這裡的col 1確實為C1 03
接下來取出其中一個塊進行分析
這裡為了更方便的論述,我將資料ID的分佈變為123123這樣的分佈
而非連續的分佈,這樣更能清晰看到點陣圖在分佈中的變化。如果為連續
那麼會全部是是FF這樣的出現
根據DUMP的BITMAP的索引結構我取出其中一個塊進行分析如下:
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)
關於閱讀這部分資訊參考
What is 6D DB B6?
6D = 1101101
DB = 11011011
B6 = 10110110
Read from least significant bit (right to left) and left pad with zeros if not eight bits.
The resulting map is
10110110 11011011 01101101
An important point is to read the bitmap from left to right in hexadecimal in two-byte
chunks. Read each of those chunks in binary right (least significant bit) to left. If there
are not eight bits, then these would have been in effect, leading zeros, and are treated
as such. The underlined zero above demonstrates this.
全部被鎖定,這嚴重影響了併發性,所以不建議OLTP系統大量使用點陣圖索引。
但是具體點陣圖索引的內部是如何排列和組織的呢?如下將進行探討,由於水平有限可能有一定錯誤。
首先認識BITMAP索引的組織方式,首先看一下ORACLE給出的這張圖
可以看到本圖中實際上有4種顏色藍色、綠色、紅色、黃色,BITMAP 索引也是B-TREE的格式,但是其頁節點儲存
的是鍵值+ROWID範圍+點陣圖鍵的方式,這樣一來可以很明顯的感知到BITMAP所以在鍵值很少的時候其空間比較B-TREE
索引是小很多的,而在點陣圖鍵方面使用一連串的0和1來表示是否存在相應的值,這樣一來ORACLE就能快速的進行是否有
值的定位。
接下來我們進行DUMP,先建立測試表
建立這樣一張表
SQL> select id,count(*) from testt_bit group by id;
ID COUNT(*)
----------- ----------
1 100000
2 100000
3 100000
同時在分佈上是連續的,1是1-100000行,2是100001-200000行,3是剩下的
在ID列上建立BIT MAP索引
create bitmap index TEST_BIT_IND on TESTT_BIT (ID)
首先進行BITMAP索引的結構DUMP如下:
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/ora11g/diag/rdbms/test/test/trace/test_ora_5604.trc
SQL> alter session set events 'immediate trace name treedump level 76306';
*** 2015-03-18 00:40:35.111
----- begin tree dump
branch: 0x1000333 16778035 (0: nrow: 8, level: 1)
leaf: 0x1000334 16778036 (-1: nrow: 2 rrow: 2)
leaf: 0x1000335 16778037 (0: nrow: 2 rrow: 2)
leaf: 0x1000336 16778038 (1: nrow: 2 rrow: 2)
leaf: 0x1000337 16778039 (2: nrow: 2 rrow: 2)
leaf: 0x1000338 16778040 (3: nrow: 2 rrow: 2)
leaf: 0x1000339 16778041 (4: nrow: 2 rrow: 2)
leaf: 0x100033a 16778042 (5: nrow: 2 rrow: 2)
leaf: 0x100033b 16778043 (6: nrow: 1 rrow: 1)
----- end tree dump
這裡清楚的看到了這個點陣圖索引的層次,首先它只有2層,1個根節點8個頁節點,每個葉節點包含2個索引條目(最後一個節點除外)
接下來我們DUMP根節點:
根據DBA(block adress)16778035進行換算
SQL> select dbms_utility.data_block_address_file(16778035),
2 dbms_utility.data_block_address_block(16778035) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------ ------------------------------
4 819
然後alter system dump datafile 4 block 819進行DUMP
header address 47810796042828=0x2b7bd183ba4c
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 7
kdxcofbo 42=0x2a
kdxcofeo 7972=0x1f24
kdxcoavs 7930
kdxbrlmc 16778036=0x1000334
kdxbrsno 0
kdxbrbksz 8056
kdxbr2urrc 0
關於這一部分引用一個文件(作者不詳)
其中的kdxcolev表示索引層級號,這裡由於我們轉儲的是根節點,所以其層級號為1。對葉子節點來說該值為0;
kdxcolok表示該索引上是否正在發生修改塊結構的事務;kdxcoopc表示內部操作程式碼;kdxconco表示索引條目中列的數量;
kdxcosdc表示索引結構發生變化的數量,當你修改表裡的某個索引鍵值時,該值增加;kdxconro表示當前索引節點中索引條目的數量,
但是注意,不包括kdxbrlmc指標;kdxcofbo表示當前索引節點中可用空間的起始點相對當前塊的位移量;
kdxcofeo表示當前索引節點中可用空間的最尾端的相對當前塊的位移量;kdxcoavs表示當前索引塊中的可用空間總量,
也就是用kdxcofeo減去kdxcofbo得到的。kdxbrlmc表示分支節點的地址,該分支節點存放了索引鍵值小於row#0(在轉儲文件後半部分顯示)
所含有的最小值的所有節點資訊;kdxbrsno表示最後一個被修改的索引條目號,這裡看到是0,表示該索引是新建的索引;
kdxbrbksz表示可用資料塊的空間大小。實際從這裡已經可以看到,即便是PCTFREE設定為0,也不能用足8192位元組。
row#0[8044] dba: 16778037=0x1000335
col 0; len 2; (2): c1 02
col 1; len 3; (3): 01 00 03
col 2; TERM
row#1[8031] dba: 16778038=0x1000336
col 0; len 2; (2): c1 02
col 1; len 4; (4): 01 00 03 f8
col 2; TERM
row#2[8019] dba: 16778039=0x1000337
col 0; len 2; (2): c1 03
col 1; len 3; (3): 01 00 04
col 2; TERM
row#3[8006] dba: 16778040=0x1000338
col 0; len 2; (2): c1 03
col 1; len 4; (4): 01 00 04 bf
col 2; TERM
row#4[7998] dba: 16778041=0x1000339
col 0; len 2; (2): c1 04
col 1; TERM
row#5[7985] dba: 16778042=0x100033a
col 0; len 2; (2): c1 04
col 1; len 4; (4): 01 00 05 57
col 2; TERM
row#6[7972] dba: 16778043=0x100033b
col 0; len 2; (2): c1 04
col 1; len 4; (4): 01 00 05 f8
col 2; TERM
這一部分是具體的關於各個葉節點的位置(起始位置的葉節點已經在kdxbrlmc 16778036=0x1000334給出)
其儲存方式為COL0 鍵值+COL1其對應的表中資料塊起始的DBA(可能包含BMB LEVEL1塊)
但是這裡
row#4[7998] dba: 16778041=0x1000339
col 0; len 2; (2): c1 04
col 1; TERM
並未包含實際的表的DBA,為什麼未知
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x01000130 Data dba: 0x01000133
Extent 1 : L1 dba: 0x01000130 Data dba: 0x01000138
Extent 2 : L1 dba: 0x01000140 Data dba: 0x01000141
Extent 3 : L1 dba: 0x01000140 Data dba: 0x01000148
Extent 4 : L1 dba: 0x01000150 Data dba: 0x01000151
Extent 5 : L1 dba: 0x01000150 Data dba: 0x01000158
Extent 6 : L1 dba: 0x01000160 Data dba: 0x01000161
Extent 7 : L1 dba: 0x01000160 Data dba: 0x01000168
Extent 8 : L1 dba: 0x01000170 Data dba: 0x01000171
Extent 9 : L1 dba: 0x01000170 Data dba: 0x01000178
Extent 10 : L1 dba: 0x01000300 Data dba: 0x01000301
Extent 11 : L1 dba: 0x01000300 Data dba: 0x01000308
Extent 12 : L1 dba: 0x01000310 Data dba: 0x01000311
Extent 13 : L1 dba: 0x01000310 Data dba: 0x01000318
Extent 14 : L1 dba: 0x01000320 Data dba: 0x01000321
Extent 15 : L1 dba: 0x01000320 Data dba: 0x01000328
Extent 16 : L1 dba: 0x01000380 Data dba: 0x01000382
Extent 17 : L1 dba: 0x01000400 Data dba: 0x01000402
Extent 18 : L1 dba: 0x01000480 Data dba: 0x01000482
Extent 19 : L1 dba: 0x01000500 Data dba: 0x01000502
Extent 20 : L1 dba: 0x01000580 Data dba: 0x01000582
比如:
row#2[8019] dba: 16778039=0x1000337
col 0; len 2; (2): c1 03
col 1; len 3; (3): 01 00 04
根據COL 1 01 00 04 實際是01000400,我們在BMB LEVEL3的dump中可以找到
Extent 17 : L1 dba: 0x01000400 Data dba: 0x01000402
實際上它是一個BMB LEVEL1塊,我們可以看他的資料塊實際上是0x01000402
可以進行DUMP這個資料塊是否是C1 03這個值
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/ora11g/diag/rdbms/test/test/trace/test_ora_6108.trc
SQL> alter system dump datafile 4 block 1026;
擷取第一行
tab 0, row 0, @0x1f89
tl: 15 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 8] 67 61 6f 70 65 6e 67 32
col 1: [ 2] c1 03
tab 0, row 1, @0x1f7a
可以看到這裡的col 1確實為C1 03
接下來取出其中一個塊進行分析
這裡為了更方便的論述,我將資料ID的分佈變為123123這樣的分佈
而非連續的分佈,這樣更能清晰看到點陣圖在分佈中的變化。如果為連續
那麼會全部是是FF這樣的出現
根據DUMP的BITMAP的索引結構我取出其中一個塊進行分析如下:
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)
關於閱讀這部分資訊參考
What is 6D DB B6?
6D = 1101101
DB = 11011011
B6 = 10110110
Read from least significant bit (right to left) and left pad with zeros if not eight bits.
The resulting map is
10110110 11011011 01101101
An important point is to read the bitmap from left to right in hexadecimal in two-byte
chunks. Read each of those chunks in binary right (least significant bit) to left. If there
are not eight bits, then these would have been in effect, leading zeros, and are treated
as such. The underlined zero above demonstrates this.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-1695780/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於ORACLE組合索引內部儲存淺談Oracle索引
- Oracle索引——點陣圖索引Oracle索引
- Oracle-點陣圖索引Oracle索引
- oracle 點陣圖索引(bitmap index)Oracle索引Index
- 點陣圖索引(Bitmap Index)——從B*樹索引到點陣圖索引索引Index
- 點陣圖索引.sql索引SQL
- 點陣圖索引(Bitmap Index)——索引共用索引Index
- 點陣圖索引(Bitmap Index)——點陣圖索引與資料DML鎖定索引Index
- 關於敏捷的一次內部爭論敏捷
- 關於點陣圖索引的split及bitmap to rowid實現問題索引
- oracle點陣圖索引對DML操作的影響Oracle索引
- 【基礎知識】索引--點陣圖索引索引
- 點陣圖索引:原理(BitMap index)索引Index
- 點陣圖索引(bitmap-index)索引Index
- 【點陣圖索引】在點陣圖索引列上進行更新操作的鎖代價研究索引
- oracle相關內容索引Oracle索引
- Python點陣圖索引學習Python索引
- 點陣圖索引的工作原理 - Richard索引
- bitmap index點陣圖索引系列(一)Index索引
- Oracle Treedump命令分析索引結構內部資訊Oracle索引
- B樹索引和點陣圖索引的結構介紹索引
- 關於樹(圖論初步)圖論
- 索引內部結構探索索引
- 【索引】Bitmap點陣圖索引與普通的B-Tree索引鎖的比較索引
- zt_深入理解bitmap index點陣圖索引Index索引
- 匿名內部類中關於new Runnable ( )
- 【筆記】Oracle B-tree、點陣圖、全文索引三大索引效能比較及優缺點彙總筆記Oracle索引
- 關於oracle SCN 的討論Oracle
- 淺談java內部類Java
- 關於模式爭論的一點點思考模式
- 看索引內部的總結索引
- 使用點陣圖連線索引優化OLAP查詢索引優化
- JavaScript之內部陣列JavaScript陣列
- 關於轉儲Oracle索引資訊的相關命令Oracle索引
- 關於碳中和的一點淺談
- B-Tree索引與Bitmap點陣圖索引的鎖代價比較研究索引
- Oracle內部事件Oracle事件
- 使用點陣圖連線索引最佳化OLAP查詢索引