Oracle之位图索引

前两天看到有个SQL 查询的,当走位图索引的时候非常慢,当不走索引的事情反而更快一点。趁机会了解学习下。

先看一个数据表的结构,WORKERS

IDNAMESEXDEPTAGEHIREDATE
1zhangsanMaleDOM123201709
2lisiFemaleDOM135201707
3wangwuMaleDOM226201704
4maliuFemaleDOM228201301
5zhaoqiMaleDOM327201201
............... 

对于此表,我们看下下面几种情况:

1)不使用索引
  我们知道,不使用索引时,数据库只能Table Full Scan 所有记录,然后判断该记录是否满足查询条件进行 filter。


2)B树索引
对于性别、部门这样的字段,记录的取值范围只有两个或者几个,而数据库里面数据量反而很大。这时候如果使用B 树索引的话,甚至还要取出一半的数据。我们知道,Oracle会对我们的SQL 进行优化,一般会优先进行索引查询。这样的话 Oracle就会从硬盘上加载大量的数据,而且这些数据绝大部分还会被下一步给 filter 掉。显然,这不是我们想要的。实际上,B 树索引适合那种取值范围很广,且几乎没有重复的数据列。


3)位图索引
在Oracle 中,位图索引适用于只有几个固定值的列,如部门,性别等。

回到上面的数据例子,在上面的数据库表 WORKERS 中 在 SEX 和 DEPT 两列上加位图索引。
此时对于 SEX 这列会生成如下向量,10101...,和 01010...。

ID12345...
Male10101 
Female01010 

对于 DEPT 这列会生成如下向量, 11000...,00111...,00001...。

ID12345...
DOM111000 
DOM200110 
DOM300001 

当Oracle 使用位图索引查询时,就会对向量进行操作,比如当执行下面的SQL 查询时,会进行 and 操作。

SELECT * FROM WORKERS w where w.SEX = 'Male' and w.DEPT = 'DOM1' ;
Oracle 发现两个列上用设置了位图索引,会为该查询进行向量操作,即对 Male 向量DOM1向量 进行 and 操作。

ID12345......
Male10101  
DOM111000  
AND 结果10000  

从上面的结果看,对 Male 向量和 DOM1 向量进行 AND 操作后,得到的结果中只有 第一个为 1 。因此, 位图索引的查询结果只有第一列。

适用条件

上面也讲了,位图索引适合只有固定几个值的列。另外,位图索引适合静态数据,即不适合频繁更新的列。这个很好理解,比如用户 A 将了一个员工的 DEPT 从DOM3更新为 DOM1,这个操作会导致 DOM1 和 DOM3 的向量发生改变,Oracle 会将 锁定 DOM1 和 DOM3 的所有数据行,且只有在 用户A commit 后才解锁。在此之前,其他用户只能更新 DOM2向量的记录。无疑,这会导致性能变慢,影响系统并发。

还有,当数据库表中数据量比较大时,而查询结果数据量比较少时,最好先使用其他索引进行 filter 后,再使用位图索引进行 filter。还用上面的例子,比如以下查询:

SELECT * FROM WORKERS w where w.SEX = 'Male' and w.DEPT = 'DOM1' and HIREDATE > '201708' ;

Oracle会使用 两个列的位图索引进行查询。当该表的数据量比较大时,比如百万条。而我们的查询结果估计也只有一百条左右。

Oracle 先使用位图索引,从硬盘上加载数十万的记录,然后再用 HIREDATE 列进行过滤。这个过程中,大量的无用数据被加载到内存中,耗时耗内存,得不偿失。因此使用位图索引一定要谨慎。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值