原来曾经看过iot方面的书,今天再次读到logical rowid ,竟然怎么也不明白了。于是留下点笔墨,以增强记忆。
说logical rowid之前,首先要明确一个概念。
在IOT中,因为数据是存放在index中的,所以并不像常规表那样一行存放的位置始终不变。因此,对于常规表中的一行而言,有固定的位置,可以用physical rowid 来定位;而iot的数据存放在index中,由于index的特性,比如相同的pk值插入的多了,该叶节点需要split;比如该行的pk值变化了,该行就会被重新插入到对应的pk值所在的叶节点的位置。因此上面两种情况,都会造成一行存放的物理位置的变化。所以固定的rowid就无法正确的代表一行。
oracle为了解决这个问题,就采用logical rowid的方法。
我们可以在iot的上面再创建index,因为iot其实就是个index,所以iot上面的index就类似index上的index。这种index叫做secondary index。
primary rowid是说的index的每行上有一个信息,写的是该行实际在的位置;而logical rowid也位于secondary index叶节点上的每行上面。所以logical rowid对于iot而言,没有意义。他是写到secondary index上面的。
logical rowid 仍然是一个表的虚列,在select iot表的时候,select rowid显示不出来的。
logical rowid包含的内容是该行的pk值,该行的logical guess,和一些其他的控制信息。
logical guess指的是某行被第一次放入secondary index 的时候,该行被插入iot的位置。因此,logical guess可能在很多的一段时间后,就会stale,这个时候需要对secondary index 进行重建。才能对该logical guess进行更新,guess也就更准确些。
举一个例子:
sql> create table t
{ a int,
b int,
primary key (a,b)
}
organization index;
table created.
sql> create index t_idx on t(b);
index created.
sql>set autotrace traceonly explain
sql>select a,b from t where b=55;
Executioin Plan
————————————————————————————————–
0 select statement optimizer=CHOOSE (cost=2 card=1 bytes=26)
1 0 index (range scan) of ‘T_IDX’ (non-unique)
(cost=2 card=1 bytes=26)
注意上面的,t_idx 就是secondary index,index上的index。如果是where 后面的条件是a=。。,那么就直接查找iot,走index。可是这里条件是b=55,不能够使用pk来进行查找,还好我们有了secondary index。但是注意红色的执行计划。并没有常规的 access by rowid一步。为什么?因为有了 logical rowid。根据secondary index,然后就可以根据该行的primary key value进行logical guess了。直接读取IOT
再多说一个问题,既然数据是放在index 中,为什么还需要创建secondary index 呢?从上面的例子可以简单看出来。因为查询并不一定总是围绕着pk来进行,而且pk可能有多个列,就如上面的例子一样,如果没有secondary index,那么对列b 的查询就需要对iot 全面扫描了。
