浅析bitmap index的结构(续)

| No Comments

在"浅析bitmap index的结构"一文中,可以看到trace文件的内容和BBED dump以及10608的结果不一致,我当时不明白这为什么,其实这是因为顺序的问题,oracletrace文件还是没有问题的,是我错了

 

具体来说就是这样:第一次的trace文件是在我事先建好bitmap index后再插入数据后形成的trace,后来的BBED dump以及10608的结果是在我先drop掉上述bitmap index(此时t1里的数据还在),再建立bitmap index后形成的结果。也就是说两种结果的产生顺序并不一样,当然就没有可比性了

 

我们来证明一下:

 

1先建立空的bitmap index,后往里插入数据

SQL> create table t1(id number);

 

Table created

 

SQL> create bitmap index idx_t1 on t1(id);

 

Index created

 

先后插入id1,2,1,1,25条记录后commit

 

SQL> select /*+ full(t1) */id,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid)||'_'||dbms_rowid.rowid_row_number(rowid) location from t1;

 

        ID LOCATION

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

         1 10_67768_0

         2 10_67768_1

         1 10_67768_2

         1 10_67768_3

         2 10_67768_4

 

dump上述bitmap index block如下是dump出来的trace文件的内容:

Leaf block dump

===============

header address 4567724132=0x11041f064

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 7859=0x1eb3

kdxcoavs 7938

kdxlespl 0

kdxlende 0

kdxlenxt 0=0x0

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8032

row#0[7886] flag: ------, lock: 2, len=27

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

col 1; len 6; (6):  00 00 00 00 00 00

col 2; len 6; (6):  02 81 08 b8 00 07

col 3; len 7; (7):  f8 d2 d5 80 c7 0e 0d

row#1[7859] flag: ------, lock: 2, len=27

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

col 1; len 6; (6):  00 00 00 00 00 00

col 2; len 6; (6):  02 81 08 b8 00 07

col 3; len 7; (7):  f8 d2 d5 80 c7 0e 12

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

从上述trace文件来看:对于键值为1(即c1 02)的bitmap index而言,其rowid的下限是0,上限是02 81 08 b8 00 07encoded bitmapf8 d2 d5 80 c7 0e 0d

 

我们现在来看一下BBED dump上述bitmap index block的结果:

BBED> set file 10

        FILE#           10

 

BBED> set block 67853

        BLOCK#          67853

 

BBED> set offset 7986

        OFFSET          7986

 

BBED> dump

 File: /iprat02/ipratest/caipratbs_02.DBF (10)

 Block: 67853            Offsets: 7986 to 8191           Dba:0x0281090d

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

 000202c1 02060000 00000000 06028108 b8000707 f8d2d580 c70e0d00 0202c102

 06000000 00000006 028108b8 000707f8 d2d580c7 0e050002 02c10306 00000000

 00000602 8108b800 0706c1c0 d580c70e 000202c1 03060000 00000000 06000000

 000000ff 000202c1 02060000 00000000 06028108 b8000706 c0c0d580 c70e0002

 02c10206 00000000 00000600 00000000 00ffc33d 323ec124 00004120 7461736b

 20666f72 2053514c 20416363 65737320 41647669 736f7220 68617320 6265656e

 20657865 63757465 642e90cc 060b

 

 <32 bytes per line>

BBED dump出来的结果我们可以看出此时的物理存储和trace文件里的内容一致只不过因为是先建的bitmap index后来一条一条往里面插入所以index里面还保留了这种插入的痕迹(比如上述index里并不是只有一个c1 02)。

 

好了,这里我们来解释一下我在"浅析bitmap index的结构"一文里不明白的问题:

1、为什么对于键值为1(即c1 02)的bitmap index而言,其rowid的下限是0

答:因为上述bitmap index在建立的时候实际上是空的(因为当时表t1里还没有数据),所以其rowid的下限是0,如果在创建bitmap index的时候表t1里有数据,这时候其rowid的下限就不是0了

 

2、对于键值为1(即c1 02)的bitmap index而言,怎样理解其encoded bitmap

答:oraclebitmap index在存储的时候会压缩,上述encoded bitmapf8 d2 d5 80 c7 0e 0d,第一个bytecontrol byte,这里是f8,即11111000

这里头两个bit11,是固定的;

中间的三个bit111,表示后面跟了一大堆byte,这一大堆byte和上述中间的三个bit联合起来就表示oracle在生成键值为1(即c1 02)的bitmap index的时候skip掉了多少个zero byte

最后的三个bit000表示除了上述control byte和中间那一堆用来表示skip掉了多少个zero bytebyte以外还有一个byte是真正用来表示bitmap的值的分布的,这个真正用来表示bitmapbyte就是上述encoded bitmap的最后一个byte,即0d

 

额外说一句,从上述BBED dump的内容可以看出来,oracle这里在insert到同一个bitmap index block的时候是会调整原来已经插入的rowrowid的上限和下限的,比如oracle这里会把以前插入的rowrowid的上限和下限都调整为0,如上述BBED dump中红颜色所示。

Leave a comment