Oracle基于函数的索引

  • 基于函数的索引
    比如执行如下一条SQL语句:select * from emp where upper(ename) = ‘KING’,即使在ename上建立了索引,还是会全表扫描emp表,将里面的ename字段改成大写跟常量KING进行比较。如果我们建立一个基于函数的索引,比如:create index emp_upper_idx on emp(upper(ename)); 这个时候,我们只需要按区间扫描小部分数据,然后获取rowid取访问表中的数据,这个速度是比较快的。
    基于函数的索引,类似于普通的索引,只是普通的索引是建立在列上,而它是建立在函数上。当然这回对插入数据有一定影响,因为需要通过函数计算一下,然后生成索引。但是插入数据一般都是少量插入,而查询数据一般数据量比较大。为了优化查询速度,稍微降低点插入速度是可以承担的。
    函数索引还有一个功能,只对部分行建立索引。假设有一个很大的表,有一列叫做FLAG,只可能取Y和N。假设大部分数据是Y,小部分数据是N,我们需要将N修改成Y。如果建立一个普通索引,这个索引会非常大,而且将N修改成Y的时候,维护这个索引开销会很大。不过这个表听起来比较适合位图索引,但这是一个事物系统(OLTP),可能有很多人同时插入记录,或者进行修改。那么位图索引也不适合。所以,如果我们只是在值为N的行上建立索引,就比较好办了。
    只在值为N的行建立索引SQL:create index flag_index on big_table(case flag when ‘N’ then ‘N’ end);这样一个索引大小会大大降低,而且维护成本也会很低的。前提是我们只对值为N的行感兴趣。

  • 位图索引
    位图索引的适用条件
    位图索引适合只有几个固定值的列,如性别、婚姻状况、行政区等等,而身份证号这种类型不适合用位图索引。
    位图索引适合静态数据,而不适合索引频繁更新的列。

举个例子,有这样一个字段busy,记录各个机器的繁忙与否,当机器忙碌时,busy为1,当机器不忙碌时,busy为0。

这个时候有人会说使用位图索引,因为busy只有两个值。好, 我们使用位图索引索引busy字段!假设用户A使用update更新某个机器的busy值,比如update table set table.busy=1 where rowid=100;,但还没有commit,而用户B也使用update更新另一个机器的busy值,update table set table.busy=1 where rowid=12; 这个时候用户B怎么也更新不了,需要等待用户A commit。

原因:用户A更新了某个机器的busy值为1,会导致所有busy为1的机器的位图向量发生改变,因此数据库会将busy=1的所有行锁定,只有commit之后才解锁。

问题: 为什么更新了某个机器的busy值为1,会导致所有busy为1的机器的位图向量发生改变,因此数据库会将busy=1的所有行锁定?

答案请看位图索引的存储结构。

位图的存储,位图中位的个数和表中的记录数项目,

比如下面婚姻状况表
姓名(Name) 性别(Gender) 婚姻状况(Marital)
张三 男 已婚
李四 女 已婚
王五 男 未婚
赵六 女 离婚
孙七 女 未婚

表中有5行记录,所以创建的记录会有5位
性别列-男的位图: 10100
性别列-女的位图: 01011
已婚列的位图: 11000
未婚列的位图: 11000
离婚列的位图: 11000
所以现在知道了吧, 当要更新位图索引时,就要更新这个位图,那么将会锁定整个位图或者要更新的这个位所在的块。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值