我前篇<<
DBA写给开发的索引经验
>>说了一堆乱加索引的情况,但总得来说开发通常都很好学的,有时也会翻翻数据库性能优化的书,也
常常会被书中的一些新特性或名词所吸引,而尝试使用它们。不乏成功案例,但误用特性的情况也不少,其中索引被误用的情况就常见。
预备讲几种项目中常见的,不过我在这里只拿
位图索引(Bitmap Index)说一下事(
只针对OLTP环境)。
书上通常会说,
对于基数比较小的列,如果只有有限的几个固定值,如上表中的性别、婚姻状况等等,要为其建立索引的话,采用的就应该是位图索引,而不是B树索引。
有很多性急的开发一看到这,就忍不住心花怒放。 对啊,可不是么,系统上到处都是这类的,如状态啊,什么类型啊,
属性之类,很多。 经常做为查询条件使用。 位图索引不正好可以用上去吗? 然后就开干了。
查询确实是快了。但如果刚好哪个表,总数据量比较大,用户很多并发量大需要频繁地更新的作业就比较悲催了。
有很大可能会碰到响应时间很长的现象,而你检查CPU,内存和I/O都很正常,但更新速度就是上不去。尝试将表上加的位图索引删除掉,
可能就解决问题了。
原因简单来说,是因为
加了位图索引的列,每次修改一个值,表中每个等于这个值的行都会锁定。
即一行有更新,其它相同值的行跟着锁定。
其事务更新就被阻塞,作业被挂起。而像性别,状态...这类列。相同值的行会相当多,数据量越大的表,锁定的行就越多,用户多并发越大,排队就越多。
排队时间长了。用户就来投诉了。
那B*树索引就是系统默认的那个索引有没有这种问题呢,B*树的索引键与表的行是有对应关系的,不像位图索引一扫一大片,一个索引值对应多行。所以B*树索引是没这种问题的。
那位图索引到底在哪些地方用比较合适呢,
它适合于那种查询比较多,但更新并发量不大,不频繁的表。
比如归档后的一些单据或操作的历史记录表这类,适应用而定。
说了这么多就是想提醒下加索引,
使用新特性要小心。要了解其优点,更要了解它的缺点。
总之情况要考虑的越多越好。
很多DBA做得越久,胆子越小是有道理的。
附条位图索引的创建例子:
create bitmap index idx_xcl on test(status);
另外,位图索引的实现原理很有意思,后面有空再写一篇,用C++实现一个位图的算法给你们看看,像位图,树,各种数据结构
在项目中用得很多的,在数据库中查看原理时常常能找到对照。
Blog: http://blog.csdn.net/xcl168