zoukankan      html  css  js  c++  java
  • bitmap index 的研究

    前一篇blog探讨了 bitmap index 的 start rowid,end rowid  是怎么存储的,现在 继续研究 bitmap index

    SQL> create table test as select * from dba_objects where 1=2;

    Table created

    SQL> insert into test select * from dba_objects where rownum<=100;

    100 rows inserted

    SQL> commit;

    Commit complete

    SQL> select distinct status from test;

    STATUS

    -------

    VALID

    SQL> select min(object_id),max(object_id) from test;

    MIN(OBJECT_ID) MAX(OBJECT_ID)

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

                 2            101

    SQL> update test set status='INVALID' where object_id>11 and object_id<22;

    10 rows updated

    SQL> commit;

    Commit complete

    SQL> select dbms_rowid.rowid_relative_fno(rowid)file_id, dbms_rowid.rowid_block_number(rowid)block_id,

      2  dbms_rowid.rowid_row_number(rowid) row# from test where object_id>11 and object_id<22;

       FILE_ID   BLOCK_ID       ROW#

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

             6         28          0

             6         28          3

             6         28         10

             6         28         11

             6         28         18

             6         28         19

             6         28         22

             6         28         32

             6         28         37

             6         28         43

    10 rows selected

    这里我们知道这10行存储在file_id 6 block_id 28,行0,3 ......37,43等等

    SQL> create bitmap index b_status on test(status) ;

    Index created

    SQL> select file_id,block_id from dba_extents where segment_name='B_STATUS';

       FILE_ID   BLOCK_ID

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

             6         33

    这里我们知道ORACLE用了一个区来存储bitmap b_status,由于测试环境是10g,我采用的是本地管理的表空间,那么从第33个block开始到35个block是

    位图管理的信息,所以本实验不dump这些block.

    SQL> select blocks from dba_segments where segment_name='B_STATUS';

        BLOCKS

    ----------

             8

    SQL> alter system dump datafile 6 block min 36 block max 40;

    System altered

    部分dump信息

    Leaf block dump

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

    header address 142746212=0x8822264

    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 7964=0x1f1c

    kdxcoavs 7924

    kdxlespl 0

    kdxlende 0

    kdxlenxt 0=0x0

    kdxleprv 0=0x0

    kdxledsz 0

    kdxlebksz 8036

    row#0[8004] flag: ------, lock: 0, len=32

    col 0; len 7; (7):  49 4e 56 41 4c 49 44  --- 这一行表示索引key值 ,将其还原表示 INVALID 具体转换过程见下面

    col 1; len 6; (6):  01 80 00 1c 00 00     ---这一行表示start rowid 取0180001c将其转换为 file_id=6,block_id=28,00 00 表示 start row#为0

    col 2; len 6; (6):  01 80 00 1c 00 2f     ---这一行表示end rowid ,取0180001c将其转换为file_id=6,block_id=28,2f表示end row#为 47

    col 3; len 7; (7):  cd 09 0c 4c 00 21 08  ---这一行表示 bitmap segment,用1表示这一行存在,0表示不存在,具体解释见下面

    row#1[7964] flag: ------, lock: 0, len=40

    col 0; len 5; (5):  56 41 4c 49 44        

    col 1; len 6; (6):  01 80 00 1c 00 00     

    col 2; len 6; (6):  01 80 00 1d 00 07     

    col 3; len 17; (17):  cf f6 f3 b3 ff de f7 ff ff cb ff ff ff 0f f8 4b ff

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

    buffer tsn: 7 rdba: 0x01800025 (6/37)

    scn: 0x0000.0008f5c1 seq: 0x01 flg: 0x06 tail: 0xf5c10601

    frmt: 0x02 chkval: 0xa5ba type: 0x06=trans data

    Hex dump of block: st=0, typ_found=1

    还原dump值的存储过程

    SQL> declare n varchar2(2000);

      2       begin

      3       dbms_stats.convert_raw_value('494e56414c4944',n);

      4       dbms_output.put_line(n);

      5       end;

      6  /

    INVALID

    根据rowid得到file_id,block_id

    SQL> select to_number('0180001c','xxxxxxxxxxxx') from dual;

    TO_NUMBER('0180001C','XXXXXXXX

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

                          25165852

    SQL> select dbms_utility.data_block_address_file('25165852') FILE_ID,dbms_utility.data_block_address_block('25165852') BLOCK_ID from dual;

       FILE_ID   BLOCK_ID

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

             6         28

    SQL> select to_number('2f','xx') from dual;

    TO_NUMBER('2F','XX')

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

                      47

    bitmap segment 信息,首先将其转换为2进制,注意,hex_to_bin函数是我自己写的

    SQL> select hex_to_bin('cd090c4c002108') from dual;

    HEX_TO_BIN('CD090C4C002108')

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

    1100 1101 0000 1001 0000 1100 0100 1100 0000 0000 0010 0001 0000 1000

    根据DSI 042上面关于bitmap index的描述 每八位 组成一个chunk,阅读的时候从右到左,首八位不表示位图信息,那么转换的结果如下

    10010000      00110000       00110010             00000000 10000100      00010000  注意,这里row#信息以0开始

    row#0,row#3,  row#10,row11, row#18,row#19,row#22    无     row#32,row#37  row#43

    ok,现在各位能明白bitmap index 了吧,rowid 里面记录的 file_id,block_id是准确的,要想定位某一行必须通过bitmap segment来定位

    下面继续实验

    SQL> select distinct dbms_rowid.rowid_block_number(rowid)block_id from test;

      BLOCK_ID

    ----------

            28

            29

    可以看到这个表用了两个block

    SQL> select object_id,status from test where dbms_rowid.rowid_block_number(rowid)=29;

     OBJECT_ID STATUS

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

            94 VALID

            95 VALID

            96 VALID

            97 VALID

            98 VALID

            99 VALID

           100 VALID

           101 VALID

    8 rows selected

    SQL> update test set status='INVALID' where object_id=94;

    1 row updated

    SQL> commit;

    Commit complete

    SQL> select dbms_rowid.rowid_relative_fno(rowid)file_id, dbms_rowid.rowid_block_number(rowid)block_id,

      2   dbms_rowid.rowid_row_number(rowid) row# from test where object_id>11 and object_id=94;

       FILE_ID   BLOCK_ID       ROW#

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

             6         29          0

    SQL> alter system dump datafile 6 block min 36 block max 40;

    System altered

    部分dump信息

    Leaf block dump

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

    header address 134357604=0x8022264

    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 7890=0x1ed2

    kdxcoavs 7922

    kdxlespl 0

    kdxlende 0

    kdxlenxt 0=0x0

    kdxleprv 0=0x0

    kdxledsz 0

    kdxlebksz 8036

    row#0[7930] flag: ------, lock: 2, len=34

    col 0; len 7; (7):  49 4e 56 41 4c 49 44  ---这里表示INVALID

    col 1; len 6; (6):  01 80 00 1c 00 00     ---start rowid 的 file_id 6,block_id 28, 起始row#为0

    col 2; len 6; (6):  01 80 00 1d 00 07     ---end rowid 的   file_id 6,block_id 29  结束row#为7 ,要理解row#,它只是表示一个范围而已

    col 3; len 9; (9):  cd 09 0c 4c 00 21 08 c0 3f ----具体分析步骤见下面

    row#1[7890] flag: ------, lock: 2, len=40

    col 0; len 5; (5):  56 41 4c 49 44

    col 1; len 6; (6):  01 80 00 1c 00 00

    col 2; len 6; (6):  01 80 00 1d 00 07

    col 3; len 17; (17):  cf f6 f3 b3 ff de f7 ff ff cb ff ff ff 0f f8 4b fe

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

    根据rowid得到file_id,block_id

    SQL> select to_number('0180001d','xxxxxxxxxxxx') from dual;

    TO_NUMBER('0180001D','XXXXXXXX

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

                          25165853

    SQL> select dbms_utility.data_block_address_file('25165853') FILE_ID,dbms_utility.data_block_address_block('25165853') BLOCK_ID from dual;

       FILE_ID   BLOCK_ID

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

             6         29

    bigmap segment的分析

    SQL> select hex_to_bin('cd090c4c002108c03f') from dual;

    HEX_TO_BIN('CD090C4C002108C03F')

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

    1100 1101 0000 1001 0000 1100 0100 1100 0000 0000 0010 0001 0000 1000 1100 0000 0011 1111

    同样首先将其转换为2进制,去掉首八位,得到00001001 00001100 01001100 00000000 00100001 00001000 11000000 11000000 00111111

    然后以每八位为一个chunk,从右往左读,得到如下信息

    1001000 00110000 00110010 00000000 10000100 00010000    00000011 11111100

       这前面的 就不用再算了     奶奶的这里不能理解了 看来还得继续研究 不再同一个block的情况

    2010-03-22续

    今天google了一下,发现bitmap index dump 出来的结果和oradebug出来的不一样 看来还得继续 研究oradebug了

  • 相关阅读:
    UIFont的使用和字体类型总结
    LOJ-10100(割点个数)
    LOJ-10099(点双联通)
    poj-3177(并查集+双联通分量+Tarjan算法)
    图论:割点和桥
    牛客训练五:炫酷数学(思维)
    牛客训练五:炫酷路途(c++与dp)
    并查集的两种实现(按秩合并+路径压缩)
    牛客训练六:海啸(二维树状数组+vector函数的使用)
    牛客训练六:美食(贪心)
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330604.html
Copyright © 2011-2022 走看看