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

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

 

转载于:https://www.cnblogs.com/zwl715/p/3855990.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle服务器和客户端字符集的查看和修改

一、什么是oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储&#xff0c;处理&#xff0c;检索数据。它使数据库工具&#xff0c;错误消息&#xff0c;排序次序&#xff0c;日…

Java 按位运算符(,|,^,,)

&(按位与) 定义&#xff1a;针对二进制&#xff0c;只要有一个为0&#xff0c;就为0。2 & 5 02的二进制&#xff1a;00000000 00000000 00000000 000000105的二进制&#xff1a;00000000 00000000 00000000 00000101 |(按位或) 定义&#xff1a;针对二进制&#xff0c…

Oracle 多行合并一行 方法

假如有如下表&#xff0c;其中各个i值对应的行数是不定的 Sql代码 SQL> select * from t; I A D ---------- ---------- ------------------- 1 b 2008-03-27 10:55:42 1 a 2008-03-27 10:55:46 1…

Docker 简单入门(一)

Docker 简介 Docker是一个开源的容器引擎&#xff0c;它有助于更快地交付应。Docker可将应用程序和基础设施层隔离&#xff0c;并且能将基础设施当作程序-样进行管理。使用Docker&#xff0c;可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 Docke…

PDF解决方案(2)--文件转PDF

相关专题链接&#xff1a; PDF解决方案&#xff08;1&#xff09;--文件上传 PDF解决方案&#xff08;2&#xff09;--文件转PDF PDF解决方案&#xff08;3&#xff09;--PDF转SWF PDF解决方案&#xff08;4&#xff09;--在线浏览 前言&#xff1a;上一篇中讲到的文件上传&…

Docker 常用命令(二)

Docker 镜像常用命令 搜索镜像 可使用 docker search 命令搜索存放在 Docker Hub 中的镜像。例如&#xff1a; docker search java 执行该命令后&#xff0c; Docker 就会在 Docker Hub 中搜索含有 java 这个关键词的镜像仓库。执行该命令后&#xff0c;可看到类似于如下的表格…

Docker 使用Dockerfile构建Docker(三)

Dockerfile 简单使用 先来编写一个最简单的 Dockerfile。 例如&#xff1a; FROM nginx RUN echo <h1>使用Dockerfile构建镜像</h1> > /usr/share/nginx/html/index.html 该 Dockerfile 非常简单&#xff0c;其中的 FORM 、 RUN 都是 Dockerfile 的指令。 FROM …

网络流之最大流问题

Reference&#xff1a; http://blog.csdn.net/rrerre/article/details/6751520 http://blog.csdn.net/y990041769/article/details/21026445 http://www.nocow.cn/index.php/Translate:USACO/NetworkFlow 最大流Edmonds_Karp算法模板&#xff1a; EK算法即增广路算法。 最大流最…

delphi读取excel

简单的例子 1 procedure TForm1.Button1Click(Sender: TObject);2 var3 ExcelApp,MyWorkBook: OLEVariant;4 begin5 opendialog1.Filter:Microsoft Excel Workbook (*.xls)|*.XLS|; 6 edit2.Text : sheet1;7 if opendialog1.Execute then8 begin9 edit1.Text:o…

Docker-compose 常用命令及网络设置(五)

Docker Compose 常用命令 build 构建或重新构建服务。服务被构建后将会以 project_service的形式标记,例如:comoretest db。help 査看指定命令的帮助文档,该命令非常实用。 docker-compose所有命令的帮助文档都可通过该命令查看。 docker-compose he lp COMMAND 示例 docker-co…

浅谈 trie树 及其实现

定义&#xff1a;又称字典树&#xff0c;单词查找树或者前缀树&#xff0c;是一种用于快速检索的多叉树结构&#xff0c; 如英文字母的字典树是一个26叉树&#xff0c;数字的字典树是一个10叉树。 核心思想&#xff1a;是空间换时间.利用字符串的公共前缀来降低查询时间的开销以…

Docker-compose 安装与基本使用(四)

安装 Docker-Compose Compose有多种安装方式,例如通过 shell, pip以及将 Compose作为容器安装等。本次安装以Shell 为主。 通过以下命令自动下载并安装适应系统版本的 Compose: curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(un…

如何开始DDD(完)

连续写了两篇文章&#xff0c;这一篇我想是序的完结篇了。结合用户注册的例子再将他简单丰富一下。在这里只添加一个简单需求&#xff0c;就是用户注册成功后给用户发一封邮件。补充一下之前的代码 public class DomainService {public void Register(User user){if (_userRepo…

git pull 报错:Untracked Fles Preventing Merge

场景 使用 git pull 命令更新报错解决 找到对应的文件删除后重新打开项目。

关于string,我今天科普的

今天下午朋友讨论组上讨论一个关于string的问题&#xff0c;问题是这样的&#xff0c;string a"aaa";string ba;a"bbb",为什么测试b的值不改变&#xff1f;之前我看过一个文章&#xff0c;知道肯定不相等&#xff0c;因为引用地址的一系列问题&#xff0c;…

git pull 报错:The following untracked working tree files would be overwritten by merge

场景 使用 git pull 命令更新报错 Updating d652d1c..fa05549 error: The following untracked working tree files would be overwritten by merge:.idea/encodings.xmlPlease move or remove them before you can merge. Aborting 解决 使用 git clean -d -fx 命令即可。

SpringBoot 配置多数据源

项目Git地址&#xff1a;SpringBoot 配置多数据源&#xff1a;Jacob-multi-data-source 准备工作 准备两个数据库(此模块中两个数据库一个为本地 一个为远程&#xff0c;本地为主&#xff0c;远程为从)。然后建表。 #本地库 CREATE TABLE username (id bigint(11) NOT NULL AUT…

HDU 2912

直线关于球的多次反射&#xff0c;求最后一次反射点 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std; const double inf1e10; const double eps1e-8; struct point {doub…

EMVTag系列3《持卡人基本信息数据》

9F61 持卡人证件号 L&#xff1a;2–26 R&#xff08;需求&#xff09;&#xff1a;数据应存在&#xff0c;在读应用数据过程中&#xff0c;终端不检查&#xff1b; (PBOC2.0第五部分中规定)芯片中持卡人姓名 5F20与持卡人姓名扩展9F0B只能使用一个&#xff0c;另一个必须不…

BindingException: Parameter 'XXX' not found. Available parameters are [collection, list]

应业务需求&#xff0c;需要使用到MQ进行数据上传和下发。传递格式为JSON,服务那边下发JSON数组&#xff0c;接收端将JSON数组转换成List集合&#xff0c;调用Mybatis-plus批量添加saveBatch()。提示字段未找到... org.apache.ibatis.exceptions.PersistenceException: ### Er…