概述

oracle索引主要分为以下几种:

1. b-tree索引

Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名。CREATE INDEX语句时,默认就是在创建b-tree索引。没有特别规定可用于任何情况。

2. 位图索引(bitmap index)

位图索引特定于该列只有几个枚举值的情况,比如性别字段,标示字段比如只有0和1的情况。

3. 基于函数的索引

比如经常对某个字段做查询的时候是带函数操作的,那么此时建一个函数索引就有价值了。

4. 分区索引和全局索引

这2个是用于分区表的时候。前者是分区内索引,后者是全表索引

5. 反向索引(REVERSE)

这个索引不常见,但是特定情况特别有效,比如一个varchar(5)位字段(员工编号)含值(10001,10002,10033,10005,10016..)

这种情况默认索引分布过于密集,不能利用好服务器的并行

但是反向之后10001,20001,33001,50001,61001就有了一个很好的分布,能高效的利用好并行运算。

6.HASH索引

HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。使用HASH索引必须要使用HASH集群。

索引这么多,重点还是把握b-tree索引和位图索引,今天先介绍下oracle的位图索引。


什么是位图索引

简单点就是用位图表示的索引,oracle对于选择度底的列的每个键值建立一个位图,位图中的每一位可能对应多个列,位图中位等于1表示特定的行含有此位图表示的键值。

我们目前大量使用的索引一般主要是B-Tree索引,在索引结构中存储着键值和键值的RowID,并且是一一对应的,而位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个位图索引块可能指向的是几十甚至成百上千行数据的位置。

创建语法:

create bitmap index idx_bm_emp1_deptno on emp1(deptno);

可以使用如下的 SQL 语句查询数据库中的所有位图索引:

SELECT * FROM DBA_INDEXES D WHERE D.INDEX_TYPE='BITMAP';

查询原理

由于索引是位图,所以很多时候可以对这些索引中的位图进行位运算-(and 和 or),这样的速度明显比b树快(某些情况下)。由于位图索引可以存储null,所以可以直接通过位图索引计数(肯定是准确的)。

假设某个表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,从而降低了并发性。


位图的优点(主要针对dw)

1、减少即席查询的相应时间

2、和其它类型索引比较,真正节约了索引数据空间

3、即使在非常差的硬件上,也可能会有戏剧化的性能提升

4、高效的并行DML和LOAD操作。

5、生成索引的时候更高效,首先是不排序,其次是占用的空间少(索引空间)。

6、可以通过位图索引直接计数。


位图索引的缺点

1、不适合选择度低的列

2、如果有比较频繁的insert,update等操作,可能导致性能很底下,因为更新索引用的是行锁(可能锁定多行),而不是排它锁。

3、可能会溢出,索引数据块难于放下整个索引值,这有可能导致低效。


总结:

位图索引是为数据仓库(也就是查询环境设计的),位图索引特别不适合OLTP系统,位图索引不适合与dml频繁的环境,位图索引适用于DSS系统,位图索引不适合频繁修改的系统,弊端是严重影响并发性,因为update索引列值的时候,会锁定新值和旧值指向的所有数据行,所以使用位图索引需慎重。

后面会分享更多DBA和devops方面的内容,感兴趣的朋友可以关注下!

oracle 分组排序后取第一条_关于oracle中位图索引的探讨:概念、原理、优缺点...相关推荐

  1. ORACLE分组排序后获取第一条和最后一条值

    ORACLE分组排序后获取第一条和最后一条值 参考链接 实践 后记 参考链接 ORACLE分组排序后获取第一条和最后一条值 实践 wx_user的手机号有部分有问题,发生了串登录.原本一个用户对应一个 ...

  2. Oracle根据行号达到分组排序取第一条的效果,排序后取第一条

    Oracle数据无法根据单个字段进行分组,而mysql可以,如果想要达到根据单个字段进行分组可以查询他的行号获取rowNumber达到单个字段分组取第一条效果 SELECT * FROM (SELEC ...

  3. SQL 分组排序后取值

    SQL 分组排序后取值 场景前要: 从前有三个班级,每个班级的学生成绩各异,有一天睿智的校长希望知道这一年中,每个班级近一年里所有的学生成绩信息,和查询每个班级近一年里所有第一名的学生成绩信息,故事由 ...

  4. Oracle排序后获取第一条和最后一条值

    需求:查询一天中第一条和最后一条数据 原始表 select * from table1 ; 步骤1:使用row_number() over() 函数对时间排序,一个正序,一个倒序. select t. ...

  5. oracle排序后获取第一条数据

    首先想说下,其实很简单的 select * from (select * from testStudent order by id desc) where rownum=1; 看上面的sql语句 先执 ...

  6. hive窗口函数分组排序并取第一个值_Hive(七)Hive分析窗口函数

    cookie1,2015-04-10,1 cookie1,2015-04-11,5 cookie1,2015-04-12,7 cookie1,2015-04-13,3 cookie1,2015-04- ...

  7. oracle和sql server取第一条记录的区别以及rownum详解

    我们知道学生可能有重名的情况,那么当重名的时候假设只需要取得重名结果集中的第一条记录. sql server:select top(1) num,Name from M_Student where n ...

  8. mysql 查询重复记录 取第一条_取出重复记录的第一条

    这几天在查询购买记录,其中一个需求就是查出来客户首次购买的产品时间和产品名称.说白了,就是在一段时间内,去取出来用户的第一次购买记录,再清楚一些就是在一堆重复的记录中取出第一条购买记录. 这个问题捉只 ...

  9. oracle排序后的第一条记录

    该查寻语句没有经过任何的优化,因为oracle没有SQL的TOP关键字,但是有一个ROWNUM的列,因此,可以通过ROWNUM来进行查询.oracle的关于rownum的参考手册里面提到了    分析 ...

最新文章

  1. 2017.1.9版给信息源新增:max_len、max_db字段
  2. scala 定义空的list_18.scala的型变
  3. phpAdmin数据库管理套件
  4. 程序员,活得是本事:30 岁后的 人生建议
  5. eviews 9.5新版本——平均预测、面板效应检验
  6. oracle 某一字段取反
  7. Ubuntu常用软件安装
  8. Premiere 视频基本调色
  9. perl学习(4) 子程序
  10. IT行业是吃青春饭的吗?
  11. wordpress文章页面添加版权信息的四种方法
  12. 电赛2019年F题纸张测量FDC2214的初始化代码(含STM32f103zet6和f103c8t6)胎教式
  13. mnist数据集在FATE上应用
  14. OpenWRT(十)web页面更新固件
  15. android surfaceflinger 老罗,《老罗的Android之旅》阅读笔记——SurfaceFlinger服务
  16. Java修炼之凡界篇 筑基期 第06卷 面向对象 第03话 构造器
  17. 解决思科 Cisco Packet Tracer 7.2登录问题
  18. 线性调频脉冲模糊函数公式较为详细推导
  19. 实战:垃圾短信分类检测
  20. Wind量化接口常见错误码

热门文章

  1. 手机能打开的表白代码_数据分析移动化:打开手机就能做分析
  2. vue项目打包之后放在服务器上测试的时候访问不到本地json数据的解决方法
  3. springboot扫描组件_springboot多模块包扫描问题的解决方法
  4. python最新排名_最新编程语言排名:JS位列第一 Python超Java
  5. Android studio删除sdk的方法(图文教程)
  6. iPhone 路径大全
  7. linux中传输文件方法,Linux快速传输文件几种方法
  8. java集成groovy
  9. python dictionary的遍历
  10. oracle exp imp