数据结构索引之杀死攻略(三)

接上一篇《数据结构索引之杀死攻略(二)》:https://blog.csdn.net/wydyd110/article/details/81945803

目录

4 位索引技术(位图索引BitMap Index)

4.1 位图索引的故事

4.2  位图索引是啥???

4.3 位图索引的适用条件

5  红黑树

5.1 红黑树的特征

5.2 红黑树的阶

5.3 红黑树的插入

5.4 红黑树的删除

5.5 红黑树的总结及应用


4 位索引技术(位图索引BitMap Index)

4.1 位图索引的故事

摘抄自Tomas这位Oracle大佬编著的《Expert Oracle Database Architecture-9i and 10g programming Techniques and Solutions》

一日,一群Java开发者找到Tom先生,说他们新开发的系统已经上线,但性能及其低下,他们问Tom先生能不能替他们看看问题到底出在什么地方。他们告诉Tom,他们的系统采用JSP+EJB+Oracle的典型三层架构,其中EJB中的SQL是由第三方工具产生的。Tom同志一听到EJB,就知道这个系统是不能采用SQL代码跟踪的方法来进行性能调优了。于是,Tom同志告诉这些心急火燎的Java开发者,你们系统的问题肯定在浏览器到数据库之间,但具体问题出在什么地方,我需要看看你们的数据库。

于是,Tom同志远程连接到他们的测试数据库(注意不是生产数据库),查看了几个动态性能视图(V$LOCK和V$SQL),最后终于发现了问题的所在。Tom同志发现他们的数据库中有一个位图索引(Bitmap Index)最为可疑,这个索引是建立在一个PROCESS_FLAG的字段上。PROCESS_FLAG字段表示该记录是否被处理了,可能值只有两个,一个是未处理(N),一个是已经处理(Y)。当记录初次插入数据库时,该字段的值为N,但其它进程读取并处理那些未处理的记录(值为N的记录)后,这个字段的值就更新为Y。

Tom就问这些Java开发者,你们为什么要在这个PROCESS_FLAG字段上建立位图索引呢?

其中有一个开发者振振有词的说,这是为了提高查找速度,一旦建立了位图索引,我们的程序就能快速找到那些数值为N的记录,然后处理。随后,他又拿出一本大部头的Oracle数据库参考手册,对Tom同志说,这书上都是这么说的,对那些数值非常少的字段,比如,我们的PROCESS_FLAG字段只有两个值,就应该建立位图索引,这难道有什么问题吗?

Tom同志微微一笑,没有直接回答。只见他打开SQL Plus,连接到他的本地Oracle实例,给这群开发者演示了下面及其简单的SQL代码。

SQL> create table t(processed_flag varchar2(1));

Table created.

SQL> create bitmap index t_idx on t(processed_flag);

Index created.

SQL> insert into t values('N');

1 row created.

刚才那位振振有词的开发者不服气的说,这有什么,不是很正常吗?接着Tom又打开了一个SQL Plus窗口,并连接到本地数据库,键入下面的SQL语句,奇怪的是这条SQL并不执行,而是一直在等待。下面是这条SQL的一个截图:

这些Java开发者看到这里,惊讶得目瞪口呆。其中一个开发者犹豫地说,好像这个位图索引只允许一个用户操作,如果其它用户想同时操作这个索引,那他必须等第一个用户的请求处理完成,并且提交之后,才能进行,如果第一个用户不提交,那么他必须一直等待。Tom点头表示赞同,然后给他们作了一番详细的解释: 

Oracle数据库的位图索引(Bitmap Index)确实是针对那些数值稀疏(low-cardinality,低基数)的字段,但是还应记住的一点是,它是针对那些值不经常改变的字段。在实际应用中,如果某个字段的值需要频繁更新,那么就不适合在它上面创建位图索引。在位图索引中,如果你更新或插入其中一条数值为N的记录,那么相应表中数值为N的记录(可能成百上千条)全部被Oracle锁定,这就意味着其它用户不能同时更新这些数值为N的记录,其它用户必须要等第一个用户提交后,才能获得锁,更新或插入数据。

问题找到了,修正就很简单了,Tom建议这些开发者去掉了这个位图索引,然后在PROCESS_FLAG字段上建立一个函数索引,只为那些数值为N的记录建立简单的B树索引就可以了。

故事讲完了,相信大家对位图索引还是一脸懵逼,稍安勿躁!!!

4.2  位图索引是啥???

位图索引,顾名思义,与“位”有关。计算机中所有的数据最终都转换成二进制的形式进行存储或计算。每个二进制位的取值为0或1,而取值的确切含义是由具体的上下文环境决定的。在位图索引中,每一个二进制位代表了某一行中索引列的取值情况。

有张表名为cat的表,现在要执行这样的查询:select * from cat where gender=‘公’ and character=‘乖’;

为性别字段构建位图索引,是则为1,不是则为0

形成两个向量:公10110     母01001


为性格字段构建位图索引,是则为1,不是则为0

形成两个向量:凶11010     母00101


当我们使用查询语句“select * from cat where gender=‘公’ and character='乖';”的时候 首先取出公向量10110,然后取出乖向量00101,将两个向量做and操作,这时生成新向量00100,可以发现第三位为1,则奥利奥就是我们所要找的。

4.3 位图索引的适用条件

(1)位图索引适用于数值非常少的字段。如:性别,婚姻状况等,而身份证号这种类型不适合用位图索引。

(2)位图索引适用于数值不经常改变的字段。(不理解的盆友去细细品味文章开头的那个故事)

(3)位图索引只允许一个用户操作,不适用于并发环境,否则会导致死锁。(不理解的盆友去细细品味文章开头的那个故事)

终于干掉了位图索引,露出姨母般的微笑

然而革命尚未结束,下面还有.................................................红黑树

5  红黑树

推荐博文:https://blog.csdn.net/wydyd110/article/details/81983918

5.1 红黑树的特征

(5)红黑树是满二叉树,空叶结点也看作结点

(6)n 个内部结点的红黑树,树高最大是 2 log2 (n+1)+1

(7)阶为 k 的红黑树树高 最小是 k+1,最高是 2k+1

(8)左 < 中 < 右

5.2 红黑树的阶

5.3 红黑树的插入

参考:https://blog.csdn.net/wydyd110/article/details/80097246

5.4 红黑树的删除

参考:https://blog.csdn.net/wydyd110/article/details/80097250

5.5 红黑树的总结及应用

AVL树和红黑树适合在内存中的作业,如map,set之类多为RB-tree实现。

B系列树适合外部存储应用,如在硬盘中的作业。

 

AVL:高度平衡的二叉树,一般是用平衡因子差值决定并通过旋转来实现,左右子树树高差不超过1,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。AVL树适合用于插入删除次数比较少,但查找多的情况。

 

红黑树:平衡二叉树,通过对任何一条从根到叶子的简单路径上各个节点的颜色进行约束,确保没有一条路径会比其他路径长2倍,因而是近似平衡的。所以相对于严格要求平衡的AVL树来说,它的旋转保持平衡次数较少。用于搜索时,插入删除次数多的情况下我们就用红黑树来取代AVL。

 

AVL树和红黑树都用旋转保持平衡

AVL树对每个插入操作最多需要两次次旋转(单/双旋),对每个删除操作最多需要O(logn)次旋转;

红黑树对每个插入和删除操作,任何不平衡都会在三次旋转之内解决。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值