位图索引对频繁更新的列不适用(转)

为什么位图索引只适用于低基数值,但是对频繁更新的列不适用。
原因在于,PROCESSED_FLAG列只有两个值:Y和N。对于插入到表中的记录,该列值为N(表示未处理)。其他进程读取和处理这个记录时,就会把该列值从N更新为Y。这些进程要很快地找出PROCESSED_FLAG列值为N的记录,所以开发人员知道,应该对这个列建立索引。他们在别处了解到,位图索引适用于低基数(low-cardinality)列,所谓低基数列就是指这个列只有很少的可取值,所以看上去位图索引是一个很自然的选择。
不过,所有问题的根由正是这个位图索引。采用位图索引,一个键指向多行,可能数以百计甚至更多。如果更新一个位图索引键,那么这个键指向的数百条记录会与你实际更新的那一行一同被有效地锁定。
所以,如果有人插入一条新记录(PROCESSED_FLAG列值为N),就会锁定位图索引中的N键,而这会有效地同时锁定另外数百条PROCESSED_FLAG列值为N的记录(以下记作N记录)。此时,想要读这个表并处理记录的进程就无法将N记录修改为Y记录(已处理的记录)。原因是,要想把这个列从N更新为Y,需要锁定同一个位图索引键。实际上,想在这个表中插入新记录的其他会话也会阻塞,因为它们同样想对这个位图索引键锁定。简单地讲,开发人员实现了这样一组结构,它一次最多只允许一个人插入或更新!
可以用一个简单的例子说明这种情况。在此,使用两个会话来展示阻塞很容易发生:
ORA10G> create table t ( processed_flag varchar2(1) );
Table created.
ORA10G> create bitmap index t_idx on t(processed_flag);
Index created.
ORA10G> insert into t values ( 'N' );
1 row created.
现在,如果在另一个SQL*Plus会话中执行以下命令:
ORA10G> insert into t values ( 'N' );
这条语句就会“挂起”,直到在第一个阻塞会话中发出COMMIT为止。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/110321/viewspace-608523/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/110321/viewspace-608523/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值