http://itpub.net/showthread.php?threadid=115221
SQL> truncate table tn;
表已截掉。
SQL> exec show_space('tn_bitmap',user,'INDEX');
Free Blocks.............................0
Total Blocks............................3
Total Bytes.............................12288
Unused Blocks...........................1
Unused Bytes............................4096
Last Used Ext FileId....................1
Last Used Ext BlockId...................26474
Last Used Block.........................2
PL/SQL 过程已成功完成。
SQL> alter system dump datafile 1 block 26475;
系统已更改。
Leaf block dump
===============
header address 83060828=0x4f3685c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 0
kdxcofbo 36=0x24
kdxcofeo 3940=0xf64
kdxcoavs 3904
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
----- end of leaf block dump -----
End dump data blocks tsn: 0 file#: 1 minblk 26475 maxblk 26475
索引已经清空
SQL> insert into tn values (1, 1);
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
SQL> /
已创建 1 行。
依次插入10行数据。
SQL> commit;
提交完成。
SQL> alter system dump datafile 1 block 26475;
系统已更改。
Leaf block dump
===============
header address 83060828=0x4f3685c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 11
kdxcofbo 58=0x3a
kdxcofeo 3716=0xe84
kdxcoavs 3658
kdxlespl 0
kdxlende 9
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
row#0[3913] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 1; (1): 00
row#1[3891] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 03
row#2[3869] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 07
row#3[3847] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 0f
row#4[3825] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 1f
row#5[3803] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 3f
row#6[3781] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 7f
row#7[3759] flag: -----, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 07
col 3; len 2; (2): c8 ff
row#8[3738] flag: ---D-, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 08
col 2; len 6; (6): 00 40 67 68 00 0f
col 3; len 1; (1): 00
row#9[3716] flag: -----, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 08
col 2; len 6; (6): 00 40 67 68 00 0f
col 3; len 2; (2): c8 03
row#10[3934] flag: ---D-, lock: 2
col 0; NULL
col 1; NULL
col 2; NULL
col 3; NULL
----- end of leaf block dump -----
End dump data blocks tsn: 0 file#: 1 minblk 26475 maxblk 26475
oracle对每次插入的数据都进行索引。
SQL> truncate table tn;
表已截掉。
SQL> alter system dump datafile 1 block 26475;
系统已更改。
Leaf block dump
===============
header address 83060828=0x4f3685c
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 4
kdxcosdc 0
kdxconro 0
kdxcofbo 36=0x24
kdxcofeo 3940=0xf64
kdxcoavs 3904
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
----- end of leaf block dump -----
一次性插入10条数据
SQL> insert into tn select 1,1 from user_objects where rownum < 11;
已创建10行。
SQL> commit;
提交完成。
SQL> alter system dump datafile 1 block 26475;
系统已更改。
Leaf block dump
===============
header address 83060828=0x4f3685c
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 3911=0xf47
kdxcoavs 3871
kdxlespl 0
kdxlende 1
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 3940
row#0[3911] flag: -----, lock: 2
col 0; len 2; (2): c1 02
col 1; len 6; (6): 00 40 67 68 00 00
col 2; len 6; (6): 00 40 67 68 00 0f
col 3; len 3; (3): c9 ff 03 一次性插入的数据,oracle会对整批数据进行bitmap索引。
row#1[3934] flag: ---D-, lock: 2
col 0; NULL
col 1; NULL
col 2; NULL
col 3; NULL
----- end of leaf block dump -----
End dump data blocks tsn: 0 file#: 1 minblk 26475 maxblk 26475
因此我认为对于包含bitmap索引的表应当减少对数据库操作的数量。运用批量入库的方法会使性能得到较大的提高。
有什么不对的地方还请指正。
my reply:
综合上面的实验可以看出,当单条insert发生的时候,会以8条记录为一个bitmap row 来存储,这正好是一个字节的bit,并且就算是
相同事务中的insert也会导致大量的拷贝和lock产生,严重影响性能,甚至可能发生行迁移等严重问题,所以在经常发生变化的表中
我们不应该采用 bitmap index ,当发生update 的时候情形更为复杂,暂时不予讨论了
结合
前面的第一条:
:bitmap 索引是分段存储的,也就是说很多条记录可能是分做了N段来存储,也就是有N个begin/end ,当新的记录 insert 而使用以前未曾使用过的物理地址的时候,会产生一个bitmap 段来存储,就算只有一条记录
所以我的实验中可能没有很好的做归纳,但是现象都是有的,描述的比较零散
就是说假如你们每天入库 1000万条记录
那创建 bitmap 索引的这个列有多少不同的值,如果有10万个不同的值以上,那采用 bitmap 是否合适就值得考虑了