




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
位图(bitmap)索引是另外一种索引类型,它的组织形式与B树索引相同,也是一棵平衡树。与B树索引的区别在于叶子节点里存放索引条目的方式不同。从前面我们知道,B树索引的叶子节点里,对于表里的每个数据行,如果被索引列的值不为空的,则会为该记录行在叶子节点里维护一个对应的索引条目。而位图索引则不是这样,其叶子节点里存放的索引条目如下图所示。假设某个表T里所有的记录在列C1上只具有三个值:01、02和03。在表T的C1列上创建位图索引以后,则叶子节点的内容如图9-14所示。可以看到,位图索引只有三个索引条目,也就是每个C1列的值对应一个索引条目。位图索引条目上还包含表里第一条记录所对应的ROWID以及最后一条记录所对应的ROWID。索引条目的最后一部分则是由多个bit位所组成的bitmap,每个bit位就对应一条记录。位图索引的结构当发出where c1=01这样的SQL语句时,oracle会去搜索01所在的索引条目,然后扫描该索引条目中的bitmap里所有的bit位。第一个bit位为1,则说明第一条记录上的C1值为01,于是返回第一条记录所在的ROWID(根据该索引条目里记录的start ROWID加上行号得到该记录所在的ROWID)。第二个bit位为0,则说明第二条记录上的C1值不为01,依此类推。另外,如果索引列为空,也会在位图索引里记录,也就是将对应的bit位设置为0即可。如果索引列上不同值的个数比较少的时候,比如对于性别列(男或女)等,则使用位图索引会比较好,因为它对空间的占用非常少(因为都是用bit位来表示表里的数据行),从而在扫描索引的时候,扫描的索引块的个数也比较少。可以试想一下,如果在列的不同值非常多的列上,比如主键列上,创建位图索引,则产生的索引条目就等于表里记录的条数,同时每个索引条目里的bitmap里,只有一个1,其它都是0。这样还不如B树索引的效率高。如果被索引的列经常被更新的话,则不适合使用位图索引。因为当更新位图所在的列时,由于要在不同的索引条目之间修改bit位,比如将第一条记录从01变为02,则必须将01所在的索引条目的第一个bit位改为0,再将02所在的索引条目的第一个bit位改为1。因此,在更新索引条目的过程中,会锁定位图索引里多个索引条目。也就是同时只能有一个用户能够更新表T,从而降低了并发性。位图索引比较适合用在数据仓库系统里,不适合用在OLTP系统里。SQL create table t_bitmap_test as 2 select rownum as id,trunc(dbms_random.value(1,4) as bitcol 3 from dba_objects where rownum select * from t_bitmap_test; ID BITCOL- - 1 3 2 2 3 1 4 3 5 3 6 1 7 1 8 2 9 3 10 2 11 3 12 1 13 1 14 3 15 2 16 2 17 3 18 2 19 1 20 3SQL connect hr/hr已连接。SQL alter session set events 10608 trace name context forever, level 10;会话已更改。SQL create bitmap index idx_t_bitmap_test on t_bitmap_test(bitcol);索引已创建。SQL alter session set events 10608 trace name context off;会话已更改。SQL select object_id from user_objects where object_name=IDX_T_BITMAP_TEST;OBJECT_ID- 24499SQL alter session set events immediate trace name TREEDUMP level 24499;会话已更改。10608事件用来跟踪创建bitmap索引的过程。而TREEDUMP则用来转储索引的树状结构。打开转储出来的文件:* SESSION ID:(7.13) 2008-06-10 14:33:46.000qerbiARwo: bitmap size is 8168qerbiIPI default pctfree=10qerbiIPI length=0qerbiAllocate pfree=127 space=8168qerbiStart first startqerbiRop: rid=00c01ce4.0000, new=Y , key: (2): c1 04qerbiCmpSz notfound pctfree=10qerbiCmpSz adjblksize=7351 length=0qerbiRop keysize=4 maxbm=3531kdibcoinit(3116714): srid=00c01ce4.0000qerbiRop: rid=00c01ce4.0001, new=Y , key: (2): c1 03kdibcoinit(3116698): srid=00c01ce4.0001qerbiRop: rid=00c01ce4.0002, new=Y , key: (2): c1 02kdibcoinit(311661c): srid=00c01ce4.0002qerbiRop: rid=00c01ce4.0003, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.0004, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.0005, new=N, key: (2): c1 02qerbiRop: rid=00c01ce4.0006, new=N, key: (2): c1 02qerbiRop: rid=00c01ce4.0007, new=N, key: (2): c1 03qerbiRop: rid=00c01ce4.0008, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.0009, new=N, key: (2): c1 03qerbiRop: rid=00c01ce4.000a, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.000b, new=N, key: (2): c1 02qerbiRop: rid=00c01ce4.000c, new=N, key: (2): c1 02qerbiRop: rid=00c01ce4.000d, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.000e, new=N, key: (2): c1 03qerbiRop: rid=00c01ce4.000f, new=N, key: (2): c1 03qerbiRop: rid=00c01ce4.0010, new=N, key: (2): c1 04qerbiRop: rid=00c01ce4.0011, new=N, key: (2): c1 03qerbiRop: rid=00c01ce4.0012, new=N, key: (2): c1 02qerbiRop: rid=00c01ce4.0013, new=N, key: (2): c1 04kdibcoend(3116714): erid=00c01ce4.0017status=3qerbiCon: key: (2): c1 04srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 19 25 09kdibcoend(3116698): erid=00c01ce4.0017status=3qerbiCon: key: (2): c1 03srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 82 c2 02kdibcoend(311661c): erid=00c01ce4.0017status=3qerbiCon: key: (2): c1 02srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 64 18 04这一段是创建bitmap索引的过程。我们先把被索引的列的值换算成十六进制:SQL select dump(3),dump(2),dump(1) from dual;DUMP(3) DUMP(2) DUMP(1)- - -Typ=2 Len=2: 193,4 Typ=2 Len=2: 193,3 Typ=2 Len=2: 193,24、3、2对应的十六进制则是04、03、02。也就是上面转储部分显示的key部分的键值。可以看到,oracle在创建bitmap索引时,先从第一条记录开始扫描,取出第一条记录的键值(bitcol=3),也就是“qerbiRop: rid=00c01ce4.0000, new=Y , key: (2): c1 04”。new=Y说明这是一个新的键值,因此会对应到一个索引条目。扫描第二条记录时,发现bitcol=2,该键值也是一个新的键值,因此产生一个新的索引条目,对应“qerbiRop: rid=00c01ce4.0001, new=Y , key: (2): c1 03”。扫描到第三条记录时,发现bitcol=1,该键值也是一个新的键值,因此产生第三个索引条目,对应“qerbiRop: rid=00c01ce4.0002, new=Y , key: (2): c1 02”。接下来扫描到的记录所对应的bitcol的值都是1、2、3中的一个,因此都不会产生新的索引条目,因此它们的new都为N。然后扫描完表里的所有记录以后,开始创建bitmap索引条目,也就是下面的部分:qerbiCon: key: (2): c1 04srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 19 25 09kdibcoend(3116698): erid=00c01ce4.0017status=3qerbiCon: key: (2): c1 03srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 82 c2 02kdibcoend(311661c): erid=00c01ce4.0017status=3qerbiCon: key: (2): c1 02srid=00c01ce4.0 erid=00c01ce4.17 bitmap: (4): ca 64 18 04这里的srid表示start rowid,erid表示end rowid。可以看到总共产生了3个索引条目,其key分别为:04、03、02。这3个索引条目的start rowid和end rowid的格式分两部分,中间用点隔开,点左边的表示文件号(从左边第一个字节开始的4个字节表示)和数据块号(从左边第五个字节开始的4个字节表示),点右边表示数据块里的行号。这里的显示可以看到,这20条记录都位于相同的数据块里。这里的00c0表示文件号:SQL select sys.pkg_number_trans.f_hex_to_dec(c)/4 file# FROM dual; FILE#- 3SQL select sys.pkg_number_trans.f_hex_to_dec(1ce4) as blk# FROM dual;BLK#-7396因此这20条记录在3号数据文件的7396号数据块里。我们可以使用dbms_rowid来验证。SQL select distinct dbms_rowid.rowid_relative_fno(rowid) as file#, 2 dbms_rowid.rowid_block_number(rowid) as block# 3 from t_bitmap_test; FILE# BLOCK#- - 3 7396可以看到,完全符合。每个索引条目的“bitmap : (4)”部分表示的也就是前面说到的bit位了,由1、0组成。按照前面bitmap的理论,这20条记录所对应的三个索引条目的bitmap的样子应该为:Key_value start_rowid end_rowid 理论上的bitmap 转储文件的bitmap1 00c01ce4.0 00c01ce4.0017 00100110000110000010 ca 64 18 042 00c01ce4.0 00c01ce4.0017 01000001010000110100 ca 82 c2 023 00c01ce4.0 00c01ce4.0017 10011000101001001001 ca 19 25 09转储文件里的bitmap如何对应到bit位呢 ?首先第一个字节的ca可以不考虑,暂时不知道第一个字节是什么意思。只考虑后三个字节。比如对于key_value=3来说,19,25,09对应的二进制为:SQL col c1 format a10SQL col c2 format a10SQL col c3 format a10SQL select sys.pkg_number_trans.f_hex_to_bin(19) as c1, 2 sys.pkg_number_trans.f_hex_to_bin(25) as c2, 3 sys.pkg_number_trans.f_hex_to_bin(09) as c3 from dual;C1 C2 C3- - -11001 100101 1001其中不足8位的前面用0补齐,因此,C1=00011001,C2=00100101,C3=00001001在二进制里,每个应该倒过来,从右到左排列,因此为:C3 C2 C100001001 00100101 00011001然后将它们组织为一个由多个bit位组成的bitmap的话,仍然从右到左,依次取出每个bit位,于是我们有:100110001010010010010000。我们可以把这个bit串与理论上的bitmap比较一下:10011000101001001001000010011000101001001001很明显,除了最后多出来的4个0以外,其余部分完全一致。而最后多出的0并不影响这个索引条目的使用。类似的,我们可以使用相同的方法来依次验证另外两个键值,都是符合理论值的。数据都在一个数据块里的情况比较容易理解。如果被索引的数据分布在多个数据块里呢?经常会有人问到,只记录start rowid和end rowid,如果被索引的记录分布在多个数据块里,那么oracle如何根据start rowed来找到bitmap里的bit=1所对应的记录的rowid呢?创建一个表:SQL create table t_bitmap_2(id number,bitcol char(2000);insert into t_bitmap_2 values(1,A);insert into t_bitmap_2 values(2,A);insert into t_bitmap_2 values(3,A);insert into t_bitmap_2 values(4,B);insert into t_bitmap_2 values(5,A);insert into t_bitmap_2 values(6,A);insert into t_bitmap_2 values(7,B);insert into t_bitmap_2 values(8,A);insert into t_bitmap_2 values(9,A);insert into t_bitmap_2 values(9,A);insert into t_bitmap_2 values(10,B);insert into t_bitmap_2 values(11,B);insert into t_bitmap_2 values(12,B);insert into t_bitmap_2 values(13,B);insert into t_bitmap_2 values(14,B);insert into t_bitmap_2 values(15,B);COMMIT;获得这15条记录所在的数据块号:SQL select distinct dbms_rowid.rowid_relative_fno(rowid) as file#, 2 dbms_rowid.rowid_block_number(rowid) as block# 3 from t_bitmap_2; FILE# BLOCK#- - 3 7428 3 7429 3 7430 3 7431 3 7432 3 7433可以知道,这15条记录分布在6个数据块里。然后跟踪对于bitcol列上的bitmap索引的创建过程:alter session set events 10608 trace name context forever, level 10;create bitmap index idx_t_bitmap_2 on t_bitmap_2(bitcol);alter session set events 10608 trace name context off;从转储出来的文件可以看到,最终形成了两个索引条目:qerbiCon: key: (2000):41 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20srid=00c01d04.0 erid=00c01d08.7 bitmap: (11): c8 06 c0 44 f8 b3 01 07 f8 56 06qerbiCon: key: (2000):42 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20srid=00c01d04.0 erid=00c01d09.7 bitmap: (12): 00 f8 56 06 f8 56 07 c0 a1 01 c0 44* 2008-06-10 11:21
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《LC指令应用》教学课件
- 2025年1月企业管理实务模考试题(含参考答案解析)
- 2024年1月美发师四级模拟题(含答案解析)
- 搬运设备智能控制技术研究与发展趋势考核试卷
- 纸张加工中的防潮技术考核试卷
- 橡胶合成催化剂的选择与活性评价考核试卷
- 精加工产品差异化策略考核试卷
- 天然气开采业的风险管理与运营规范考核试卷
- 玻璃仪器表面修饰与功能化考核试卷
- 租书业务与社区教育融合考核试卷
- GB/T 7702.7-2023煤质颗粒活性炭试验方法第7部分:碘吸附值的测定
- 提高我们的逆商
- 2024届一轮复习新人教版 实验17 测量玻璃的折射率 课件(35张)
- 起诉意见书(公安)
- 松下伺服驱动器说明书
- 国际友人在中国智慧树知到答案章节测试2023年西北大学
- 实验:验证动量守恒定律 说课课件
- 连杆加工工艺规程及夹具设计工序卡-工艺规程卡
- 2023年简明新疆地方史
- GB/T 41995-2022并网型微电网运行特性评价技术规范
- 钢筋加工场验收记录表
评论
0/150
提交评论