在实现位图索引的时候,出现了一些问题,引发出对rowid的一些思考。
位图索引的目的就是对于重复值较多的字段,如果通过B树索引,可能要不断的进行比较操作,而使用位图索引,则可以通过按位操作直接定位到满足条件的记录上,这样位图索引对于每个关键字的值都应该有一个位图,通过按位操作,找到记录的rowid,然后通过rowid就可以直接定位到对应的记录。
但是在达梦数据库实现的时候,rowid并不是和记录的物理位置相关联的,而只是系统中的一个唯一值而已,这样如果使用rowid的话,则找到rowid之后还需要一次聚簇索引查找操作,效率上就大打折扣了。
鉴于此,查看了一下ORACLE的rowid,ORACLE的rowid是直接和记录的物理位置相关联的,其组成为:data_object_id#+rfile#+block#+row#组成,占用10个bytes的空间, 32bit的 data_object_id#,10 bit 的 rfile#,22bit 的 block#,16 bit 的 row#. 这样ORACLE在实现位图索引的时候,可以很容易的通过rowid定位到记录的物理位置。
达梦在实现位图索引的时候,也考虑考虑修改rowid,将其改为具体的物理位置,这样一来带来了另外一个问题,达梦创建表的时候会默认的建立聚簇索引,聚簇索引的叶子节点存储了实际的记录,这样在对表进行一些更新、删除、插入操作的时候,记录的物理位置可能发生变化,那么位图索引中响应的物理位置的值也需要跟随着变化。
试验了一下ORACLE的rowid,在对表进行更新、删除、插入操作的时候,记录的rowid并不会发生变化,因此可以反推,ORACLE是不是没有建立聚簇索引,而是将记录分开存放的?这样在插入、更新、删除的时候,其物理位置并没有发生改变?这样来实现应该也是有其一定的道理的,聚簇的概念就是将相关的记录尽可能的在物理上连续存放,这样在读取的时候可以减少很多的IO操作,而将记录在物理上连续存放也是需要付出一定的代价的,即记录可能在做更新操作的时候位置被挪动,从而带来一定的开销,因此用户应该根据自己的需要在确实需要聚簇的时候来使用聚簇存储。
但是达梦数据库则默认的就创建了聚簇索引,这从一定程度上加快了记录的存取速度,但是不可避免的也带来了一部分的额外开销。
不知有没有高手来解答一下ORACLE的rowid在聚簇的时候到底是如何处理的?是否也可能发生变化?
转载于:https://blog.51cto.com/happytest/63915