行链接和行迁移
1)什么是行链接和行迁移
①行链接:指一行存储在多个块中的情况,即行链接是跨越多块的行。
②行迁移:指一个数据行由于update语句导致当前块被重新定位到另一个块(那里有充足的空间)中,但在原始块中会保留一个指针。原始块中的指针是必需的,因 为索引的ROWID项仍然指向原始位置。
行迁移是update语句当pctfree空间不足时引起的,它与insert和delete语句无关。
2)如何知道发生了行链接或行迁移
查看dba_tables的AVG_ROW_LEN列和CHAIN_CNT列。当CHAIN_CNT有值时,看AVG_ROW_LEN,它表示行的平均长度(byte),如果AVG_ROW_LEN<块大小,发生的是行迁 移,否则可能有行链接。
测试:
(一)行迁移
1、构建环境
2、先分析一下test表,确定无行迁移
analyze table test compute statistics;
可以观察到表test使用了5个块,行平均大小为3。
3、v$bh视图可以显示出t1表一共分配了8个块,具体是那些块。
4、填充这些空列,再分析test,有了行迁移
说明1000行中有865行发生了行迁移,使用的块也增加了,从之前的5个增加到了13个。
5、怎样确定那些行发生了行迁移
SQL> @/u01/oracle/rdbms/admin/utlchain.sql
SQL> analyze table scott.t1 LIST CHAINED ROWS;
SQL> select count(*) from chained_rows;
通过chained_rows表可以看到发生行迁移的列。
SQL> select table_name, HEAD_ROWID from chained_rows where rownum<=3;
Select dbms_rowid.ROWID_RELATIVE_FNO(rowid) fn,dbms_rowid.rowid_block_number(rowid) bn, rowid,c1 from test where rowid='AAASRpAAEAAAAE+AGl';
6、解决行迁移的多方法
①移动表
alter table test move;
②删除发生行迁移的行重新插入
SQL>create table test1 as select * from test where rowid in (select HEAD_ROWID from chained_rows);
SQL>delete test where rowid in (select HEAD_ROWID from chained_rows);
SQL>insert into test select * from test1;
SQL>drop table test1;
(二)行链接
1、创建环境
SQL>create table t1 (c1 varchar2(3000),c2 varchar2(3000),c3 varchar2(3000));
SQL>insert into t1 values(lpad('a',3000,'*'),lpad('b',3000,'*'),lpad('c',3000,'*'));
SQL>commit;
SQL>analyze table t1 compute statistics;
SQL>select table_name, AVG_ROW_LEN,CHAIN_CNT from user_tables where table_name='T1';
2、解决方法
SQL>create tablespace ttt datafile '/u01/oradata/vbox8db/ttt01.dbf' size 10m blocksize 16k;
SQL>alter table t1 move tablespace ttt;
SQL>analyze table t1 compute statistics;
SQL>select table_name, AVG_ROW_LEN,CHAIN_CNT from user_tables where table_name='T1';