问题描述:今天又遇到一小问题:在某个表新添加二个字段后,查询速度明显缓慢。
大家讨论怀疑是行迁移导致, 试了move 一下就ok
行迁移的影响
如果你通过一个索引来读这一行,索引会指向原来的块,那个块再指向这个新块。要得到具体的行数据,一般并不是执行两个左右的i/o 就可以得到行数据。单独来看,这不是大问题,甚至根本注意不到。不过,如果这种行所占的比例相当大,而且有大量用户在访问这些行,你就会注意到这种副作用了。访问这些数据的速度开始变慢(额外的i/o 以及与i/o 相关的闩定都会增加访问时间),缓冲区缓存的效率开始下降(需要缓存两个块,而如果行没有迁移就只需要缓存一个块)
二种情况
1行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下。这种情况下,oracle将使用链接一个或者多个在这个段中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有long、long raw、lob等数据类型的字段,这种时候行链接是不可避免的会产生的。
2当一行记录初始插入的时候事可以存储在一个block中的,由于更新操作导致行长增加了,而block的自由空间已经完全满了,这个时候就产生了行迁移。在这种情况下,oracle将会迁移整行数据到一个新的block中(假设一个block中可以存储下整行数据),oracle会保留被迁移行的原始指针指向新的存放行数据的block,这就意味着被迁移行的row id是不会改变的。
二个参数
user_tables 中的chain_cnt
--行迁移的 数量
number of rows in the table that are chained from one data block to another,
or which have migrated to a new block, requiring a link to preserve the old rowid
--行数
num_rows
例子:
analyze table t compute statistics;
table analyzed.
sql> select table_name,num_rows,chain_cnt from user_tables where table_name='t';
table_name num_rows chain_cnt
------------------------------ ---------- ----------
t 41616 3908
sql> alter table t move ;
table altered.
sql> analyze table t compute statistics;
table analyzed.
sql> select table_name,num_rows,chain_cnt from user_tables where table_name='t';
table_name num_rows chain_cnt
------------------------------ ---------- ----------
t 41616 0
,
