浅析bitmap index的结构

| 1 Comment

这篇文章里我们粗浅的分析了bitmap index的结构,但是从我测试的结果来看,dump出的trace文件的结果我真是看不懂,莫名其妙,明显跟bbed dump10608的结果不一致,不知道oracle这里是怎么弄的?

 

如下是完整的测试过程:

SQL> create table t1(id number);

 

Table created

 

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

 

Index created

 

SQL> insert into t1 values(1);

 

1 row inserted

 

SQL> insert into t1 values(2);

 

1 row inserted

 

SQL> insert into t1 values(1);

 

1 row inserted

 

SQL> insert into t1 values(1);

 

1 row inserted

 

SQL> insert into t1 values(2);

 

1 row inserted

 

SQL> commit;

 

Commit complete

 

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_66988_0

         2 10_66988_1

         1 10_66988_2

         1 10_66988_3

         2 10_66988_4

 

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

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 05 ac 00 07

col 3; len 7; (7):  f8 f6 9e fc c6 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 05 ac 00 07

col 3; len 7; (7):  f8 f6 9e fc c6 0e 12

从上述trace文件来看:对于键值为1c1 02bitmap index而言rowid的下限是0上限是02 81 05 ac 00 07encoded bitmapf8 f6 9e fc c6 0e 0d

rowid的下限怎么可能是0呢?encoded bitmap看来起也明显不对呀?

 

这里rowid的上限倒是对的,如下所示:

SQL> exec sys.cdba('28105ac','H');

 

.

The file is 10

The block is 66988

 

PL/SQL procedure successfully completed

 

我觉得这里trace文件明显不对,我们来做一个10608

SQL> drop index idx_t1;

 

Index dropped

 

SQL> oradebug setmypid

Statement processed.

 

SQL> oradebug event 10608 trace name context forever,level 10

Statement processed.

 

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

 

Index created.

 

SQL> oradebug event 10608 trace name context off

Statement processed.

 

SQL> oradebug tracefile_name

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_856500.trc

 

$ cat /u01/app/oracle/admin/ipratest/udump/ipratest_ora_856500.trc

/u01/app/oracle/admin/ipratest/udump/ipratest_ora_856500.trc

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production

......省略部分内容

qerbiARwo: bitmap size is 8168

qerbiIPI default pctfree=10

qerbiIPI length=0

qerbiAllocate pfree=127 space=8168

qerbiStart first start

qerbiRop: rid=028105ac.0000, new=Y , key: (2):  c1 02

qerbiCmpSz notfound pctfree=10

qerbiCmpSz adjblksize=7351 length=0

qerbiRop keysize=4 maxbm=3529

kdibcoinit(1104b4d60): srid=028105ac.0000

qerbiRop: rid=028105ac.0001, new=Y , key: (2):  c1 03

kdibcoinit(1104b4888): srid=028105ac.0001

qerbiRop: rid=028105ac.0002, new=N, key: (2):  c1 02

qerbiRop: rid=028105ac.0003, new=N, key: (2):  c1 02

qerbiRop: rid=028105ac.0004, new=N, key: (2):  c1 03

kdibcoend(1104b4d60): erid=028105ac.0007status=3

qerbiCon: key: (2):  c1 02

 srid=028105ac.0 erid=028105ac.7 bitmap: (2):  c8 0d

kdibcoend(1104b4888): erid=028105ac.0007status=3

qerbiCon: key: (2):  c1 03

 srid=028105ac.0 erid=028105ac.7 bitmap: (2):  c8 12

         qerbiFreeMemory: Work heap is used.

 

10608的结果我们可以看出来,rowid的下限应该是02 81 05 ac 00 00encoded bitmap应该分别是c8 0dc8 12

 

到底哪个是对的呢?我们dump一下便知:

BBED> set file 10

        FILE#           10

 

BBED> set block 67725

        BLOCK#          67725

 

BBED> set offset 7986

        OFFSET          7986

 

BBED> dump

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

 Block: 67725            Offsets: 7986 to 8191           Dba:0x0281088d

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

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 02c10306 028105ac 00000602 8105ac00 0702c812 000002c1

 02060281 05ac0000 06028105 ac000702 c80d0000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 0000e2fd 0601

 

 <32 bytes per line>

从上述dump结果里我们可以看到,oracle实际的物理存储和10608的结果是一致的

 

最后我们来说一下怎样来理解encoded bitmap

键值为1(即c1 02)的bitmap indexencoded bitmapc8 0d,还原成二进制就是:

11001000 00001101

 

这个地方要以每个byte为一组,整体是从左往右读,但组内是从右往左读,即翻译过来就是:

00010011 10110000

 

同理,对于键值为2(即c1 03)的encoded bitmap翻译过来就是

00010011 01001000

 

大家注意看,后面的一个byte的前5位分别是1011001001,这不就是ID1ID2的值的分布吗?

SQL> select /*+ full(t1) */* from t1;

 

        ID

----------

         1

         2

         1

         1

         2

这里encoded bitmap1表示有,0表示无。

所以从上述查询结果我们马上可以看出,ID1bitmap就是10110ID2bitmap就是01001

1 Comment

这里oracle的trace文件没有问题,是我错了,稍后我会详细解释一下这个问题。

Leave a comment