Oracle 位图索引

内容简介:

1.位图索引

1.1位图索引使用注意事项;

1.2 使用位图索引;

1.3 位图索引对DML操作的影响;

2.位图连接索引

2.1 明确需求后使用位图索引;

2.1创建位图连接索引的注意事项:

1.位图索引:

1.1位图索引使用注意事项:

? 一般适用于低基数列;

? 适合数据仓库;

? 对于启用位图索引的表,应尽量减少或避免DML操作;

? 如果对一张含有多列位图索引的表进行大量DML操作,应考虑将位图索引删除,DML操作结束后重建位图索引;

? 不适用于频繁持续发生DML操作的OLTP系统,会出现行锁定,阻碍更新性能;

1.2 使用位图索引

位图索引与B-TREE索引有很大的不同,一个位图索引由多个位串组成,每个位串都表示基础列中一个独立的有效值;每个位串是打开或关闭,表示该值是否用于某一行;以人员信息表th03 为例,性别(gender)字段的值(男、女、未记录),假如为其创建位图索引,那么每个位串(男、女、未记录)中的单个位表示一个给定行的值是男、女还是未记录;当判断某一列是否适合创建位图索引时,需要考虑是否符合”低基数列”,根据应用程序、数据组成以及数据库中的表的情况不同,是否创建位图索引的结论也可能不同;通常用来判断的一条基本经验法则是:”如果该列的有效值数目不足表中行数的1%,那么它就适合创建位图索引,以th03来说,表行数为:500万行,而性别列的有效值数目仅为3个( 男、女、未记录),可以确定它适合创建位图索引:

人员信息表(th03)



ID


NAME


GENDER


IDCARD


HOMEADDR


JOBNO


BIRTHDATE


1


998698


李天



440623197007253619


水晶洞1


526456


25-JUL-70


2


998699


李花



510802197007251223


水晶洞2


5785452


25-JUL-70


3


584625


李某


未记录


564551545265642155


水晶洞3


1565452


01-JUL-88

SQL> create bitmap index ind_th03_gender on th03(gender) tablespace tbs03;

Index created.

Elapsed: 00:00:01.05

SQL> execute dbms_stats.gather_table_stats(‘sywu‘,‘th03‘,cascade=>true);

PL/SQL procedure successfully completed.

Elapsed: 00:00:04.31

SQL> @/oracle/getind

TABLE_NAME INDEX_NAME COLUMN_NAME   SIZE_GB INDEX_TY STATUS COMPRESS NUM_ROWS DISTINCT_KEYS

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

TH03 IND_TH03_GENDER GENDER   .001953125 BITMAP VALID DISABLED 453 3

位图索引的创建非常快并且占用的空间也非常小;位图索引和B-TREE索引存储值的方式不同,它存储表中的每一行值(包括空值),对于B-TREE索引,单列索引不存储空值,复合索引只要有一个非空值就可以存储;所以当执行 IS NULL 或者 IS NOT NULL 查询时位图索引的效率要高于B-TREE索引:

SQL> select count(*) from th03 where gender is null;

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 5 | 1 (0)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | 5 | | |

| 2 | BITMAP CONVERSION COUNT | | 1 | 5 | 1 (0)| 00:00:01 |

|* 3 | BITMAP INDEX SINGLE VALUE| IND_TH03_GENDER | | | | |

3 - access("GENDER" IS NULL)

Statistics

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

1 recursive calls

0 db block gets

2 consistent gets

1 physical reads

如果在相同表相同列建立B-TREE索引,则该执行必须全表扫描:

SQL> select count(*) from th03 where gender is null;

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 5 | 14908 (1)| 00:02:59 |

| 1 | SORT AGGREGATE | | 1 | 5 | | |

|* 2 | TABLE ACCESS FULL| TH03 | 1 | 5 | 14908 (1)| 00:02:59 |

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

Predicate Information (identified by operation id):

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

2 - filter("GENDER" IS NULL)

Statistics

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

1 recursive calls

0 db block gets

54574 consistent gets

54562 physical reads

位图索引还可以在另外一些情况使用,如使用聚合函数:

SQL> select count(*),count(gender) from th03;

COUNT(*) COUNT(GENDER)

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

5000000 5000000

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

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

| 0 | SELECT STATEMENT | | 1 | 5 | 203 (0)| 00:00:03 |

| 1 | SORT AGGREGATE | | 1 | 5 | | |

| 2 | BITMAP CONVERSION TO ROWIDS | | 5000K| 23M| 203 (0)| 00:00:03 |

| 3 | BITMAP INDEX FAST FULL SCAN| IND_TH03_GENDER | | | | |

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

Statistics

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

0 recursive calls

0 db block gets

232 consistent gets

0 physical reads

如果你决定在应用程序中实现位图索引,应时不时的检查建立了位图索引的列的数据组成,这一点很重要,如果你算错了包含位图索引的任何列的基数,可能会对应用程序造成负面影响,如(位图索引的存储空间会增加、查询性能会降低、重建索引的时间将增加);

1.3 位图索引对DML操作的影响:

为了便于测试,我创建另一张分区表 th04,并为th04的性别、出生日期列创建位图索引,最后向它插入100万行数据:

SQL> create table th04

partition by range(id)(

partition th04_part1 values less than(1000000) tablespace tbs03,

partition th04_part2 values less than(2000000) tablespace tbs03,

partition th04_part3 values less than(3000000) tablespace tbs03,

partition th04_part4 values less than(4000000) tablespace tbs03,

partition th04_part5 values less than(5000000) tablespace tbs03,

partition th04_part6 values less than(maxvalue) tablespace tbs03

) as select * from tbbase where 1=0 ;

SQL> create bitmap index ind_th04_gender on th04(gender) local tablespace tbs03;

SQL> create bitmap index ind_th04_birthdate on th04(birthdate) local tablespace tbs03;

SQL>insert into th04 select * from tbbase where rownum<1000001;

1000000 rows created.

Elapsed: 00:00:40.24

从结果可以看出,插入100万行的数据花费40秒,从表面上看花费的时间似乎是合理的,但当数据量不断增加时,特别对于一个数据仓库环境,一天处理几百万甚至亿行数据是司空见惯的,合理的情况应考虑删除位图索引(如果是分区表则将目标分区标记为不可用),执行完DML加载操作后重建位图索引;

SQL> alter index IND_TH04_GENDER unusable;

SQL> alter index IND_TH04_BIRTHDATE unusable;

SQL> insert into th04 select * from tbbase where rownum<1000001;

禁用位图索引后,插入100万行数据只花费23 秒,对于大数据而言这或许可以提高装载数据的性能;数据装载结束后重建位图索引:

SQL> alter index ind_th04_gender rebuild partition TH04_PART1;

alter index ind_th04_gender rebuild partition TH04_PART2;

alter index ind_th04_gender rebuild partition TH04_PART3;

alter index ind_th04_gender rebuild partition TH04_PART4;

alter index ind_th04_gender rebuild partition TH04_PART5;

alter index ind_th04_gender rebuild partition TH04_PART6;

alter index ind_th04_birthdate rebuild partition th04_part1;

.........

重建分区索引也可以通过下面的命令重建:

SQL> alter table th04 modify partition th04_part1 rebuild unusable local indexes;

此命令虽然简单,但它也有不足之处,对于一个指定的分区,它只能按顺序执行;而对于每一个指令发出的命令重建分区,它可以同时执行多个语句,实现并行重建索引;

除装载数据的影响外,位图索引也会影响数据的DML操作,请观察下面的人员信息表数据:

人员信息表(th04)



ID


NAME


GENDER


IDCARD


HOMEADDR


JOBNO


BIRTHDATE


1


998698


李天



440623197007253619


水晶洞1


526456


25-JUL-70


2


998699


李四



510802197007251223


水晶洞2


5785452


25-JUL-70


.....


....

数据显示他们的出生日期是相同的,并且出生日期列(BIRTHDATE)还建立了位图索引( IND_TH04_BIRTHDATE) ,因业务错误记录两人的出生日期,so,现在对其修改:

---session 1-----

SQL> select distinct sid from v$mystat;

SID

----------

191

SQL> update th04 set birthdate=‘26-JUL-70‘ where idcard=‘440623197007253619‘;

1 row updated.

此时session 1 的用户因为业务繁忙没有及时提交,这时另一个业务员在新的会话 session2中修该另一个错误记录:

----session 2 -----

SQL> select distinct sid from v$mystat;

SID

----------

194

SQL> update th04 set birthdate=‘27-JUL-70‘ where idcard=‘510802197007251223‘;

session 2 中的用户会一直处于等待状态,因为他们修改的错误人员出生日期在更新之前在同一个位图索引位串中,当修改位串中的位信息时位串会被锁定,直到更新提交后更新位串中的位值;观察此时的锁状态:

SQL>select sid,type,id1,id2,lmode,request,ctime,block from v$lock where sid in(191,194) order by sid

SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK

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

191 AE 100 0 4 0 2052 0

191 TM 75667 0 3 0 263 0

191 TX 65562 848 6 0 263 1

191 TM 75668 0 3 0 263 0

191 TO 65927 1 3 0 286 0

194 TM 75668 0 3 0 238 0

194 TX 131081 1071 6 0 238 0

194 TM 75667 0 3 0 238 0

194 TX 65562 848 0 4 238 0

194 AE 100 0 4 0 1406 0

对于session 1(191)此时持有一个6级事务锁,并且堵塞session 2(194),它们请求的资源是一样的,这并非巧合;只有当session 1(191)提交或回退后,这个6级事物锁才会被释放,session 2(194)才能持有锁修改数据;

SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK

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

191 AE 100 0 4 0 2832 0

191 TO 65927 1 3 0 1066 0

194 TX 131081 1071 6 0 1018 0

194 TM 75667 0 3 0 1018 0

194 TM 75668 0 3 0 1018 0

194 AE 100 0 4 0 2186 0

所以建立位图索引时,应仔细分析表结构和表数据,作出明智、合理选择;以上测试因环境、版本、数据库状态测试结果可能不同;

Oracle 位图索引

时间: 2024-08-07 23:21:33

Oracle 位图索引的相关文章

oracle位图索引

以下内容主要都是关于oracle 10g位图索引,重点是存储,其它优缺点,查询机制等也略微介绍,概因为存储机制是根基.内容主要分四个部分:1)来源于http://blog.chinaunix.net/uid-20687159-id-1894992.html2)来源于http://blog.sina.com.cn/s/blog_4c6fef63010085m8.html3)来自oracle官方文档的和其它一些.  4)个人的试验,看位图索引的情况.-------------------------

数据库使用-oracle位图索引

我们目前大量使用的索引一般主要是B*Tree索引,在索引结构中存储着键值和键值的RowID,并且是一一对应的.而位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个块可能指向的是几十甚至成百上千行数据的位置.这种方式存储数据,相对于B*Tree索引,占用的空间非常小,创建和使用非常快. 位图索引的目标是为用户提供指向包含特定键值(key value

Oracle - 位图索引的适用条件

位图索引的适用条件 位图索引适合只有几个固定值的列,如性别.婚姻状况.行政区等等,而身份证号这种类型不适合用位图索引. 位图索引适合静态数据,而不适合索引频繁更新的列. 举个例子,有这样一个字段busy,记录各个机器的繁忙与否,当机器忙碌时,busy为1,当机器不忙碌时,busy为0. 这个时候有人会说使用位图索引,因为busy只有两个值.好, 我们使用位图索引索引busy字段!假设用户A使用update更新某个机器的busy值,比如update table set table.busy=1 w

索引优化原则及Oracle中索引总结

索引建立原则 确定针对该表的操作是大量的查询操作还是大量的增删改操作. 尝试建立索引来帮助特定的查询.检查自己的sql语句,为那些频繁在where子句中出现的字段建立索引. where语句中不得不对查询列采用函数查询,如upper函数,最好建立相应函数索引: 在SQL语句中经常进行GROUP BY.ORDER BY的字段上建立索引 用于联接的列(主健/外健)上建立索引: 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定: 尝试建立复合索引来进一步提高系统性能.修

Oracle索引总结(四)- Oracle索引种类之位图索引

位图索引 1.1 位图索引概述 位图索引通过位图向量,表示索引键值在表中的分布. 适用于没有大量更新操作的对象,如:OLAP数据库. 对于存在大量更新操作的索引列,不适用位图索引.因此对于OLTP并不适用. 更新位图向量时,相应位图涉及的所有数据行会被锁定,无法针对这些数据行的该索引列进行DML操作. 1.2 位图索引结构的说明 与B-tree索引的联系及区别如下: 与B-tree索引的联系:位图索引使用B-tree形式组成. 与B-tree索引的区别:位图索引的一个索引键值对应一个叶子节点.(

oracle中位图索引和B-tree索引的区别

1.适用系统的不同:位图索引适合OLAP系统,而B-tree索引适合OLTP系统. 2.占用存储空间不同:位图索引只需要很小的存储空间,而B-tree索引需要占用很大的存储空间. 3.创建需要的时间不同:位图索引创建很快,而B-tree索引创建很耗时. 4.dml操作影响大小不同:位图索引只适合海量查询,update.insert.delete时会产生负影响,而B-tree索引适合频繁的dml操作. 5.查询范围不同:位图索引适合数据重复率高的表,且可以高效地执行包含AND,OR或者XOR的逻辑

【Bitmap Index】B-Tree索引与Bitmap位图索引的锁代价比较研究

通过以下实验,来验证Bitmap位图索引较之普通的B-Tree索引锁的“高昂代价”.位图索引会带来“位图段级锁”,实际使用过程一定要充分了解不同索引带来的锁代价情况. 1.为比较区别,创建两种索引类型的测试表1)在表t_bitmap上创建位图索引[email protected]> create table t_bitmap (id number(10), name varchar2(10),sex varchar2(1)); Table created. [email protected]>

oracle数据库索引(转)

.      索引分类Ø  按存储方法分类B*树索引:B*树索引是最常用的索引,其存储结构类似书的索引结构,有分支和叶两种类型的存储数据块,分支块相当于书的大目录,叶块相当于索引到的具体的书页.一般索引及唯一约束索引都使用B*树索引. 位图索引:位置索引储存在主要用来节省空间,减少Oracle对数据块的访问,它采用位图偏移方式来与表的行ID对应,采用位图索引一般是重复值太多的表字段.位图索引在实际密集型OLTP(数据事务处理)中用得比较少,因为OLTP会对表进行大量的删除.修改.新建操作,Ora

Oracle 分区索引

分区索引(或索引分区)主要是针对分区表而言的.随着数据量的不断增长,普通的堆表需要转换到分区表,其索引呢,则对应的转换到分区索引.分区索引的好处是显而易见的.就是简单地把一个索引分成多个片断,在获取所需数据时,只需要访问更小的索引片断(块)即可实现.同时把分区放在不同的表空间可以提高分区的可用性和可靠性.本文主要描述了分区索引的相关特性并给出演示示例. 1.分区索引的相关概念a.分区索引的几种方式:表被分区而索引未被分区:表未被分区,而索引被分区:表和索引都被分区b.分区索引可以分为本地分区索引