A situation in which Oracle Database moves a row from one data block to another data block because the row grows too large to fit in the original block.
注:儘管行遷移與行鏈接是兩個不同的事情,但是在oracle內部,它們被當作一回事。所以當你檢測行遷移與行鏈接時,你應該仔細的分析當前你正在處理的是行遷移還是行鏈接。
--模擬實驗
EODA@PROD1> create table t(x int, y varchar2(50));
Table created.
EODA@PROD1> begin
2 for i in 1..1000 loop
3 insert into t values (i,'A');
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
EODA@PROD1> analyze table t compute statistics;
Table analyzed.
--chain_cnt計算了存在行遷移和行鏈接的行數
EODA@PROD1> select table_name,num_rows,chain_cnt from user_tables where table_name='T';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
T 1000 0
EODA@PROD1> update t set y=rpad('A',50,'B');
1000 rows updated.
EODA@PROD1> commit;
Commit complete.
EODA@PROD1> analyze table t compute statistics;
Table analyzed.
EODA@PROD1> select table_name,num_rows,chain_cnt from user_tables where table_name='T';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
T 1000 967
--使用腳本創建CHAINED_ROWS表
EODA@PROD1> @?/rdbms/admin/utlchain
Table created.
EODA@PROD1> desc chained_rows
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
OWNER_NAME VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CLUSTER_NAME VARCHAR2(30)
PARTITION_NAME VARCHAR2(30)
SUBPARTITION_NAME VARCHAR2(30)
HEAD_ROWID ROWID
ANALYZE_TIMESTAMP DATE
EODA@PROD1> analyze table t list chained rows into chained_rows; --自動分析並存入CHAINED_ROWS表
Table analyzed.
EODA@PROD1> select count(*) from chained_rows;
COUNT(*)
----------
967
--通過重新插入解決行遷移
EODA@PROD1> create table tmp as select * from t where rowid in (select head_rowid from chained_rows);
Table created.
EODA@PROD1> delete t where rowid in (select head_rowid from chained_rows);
967 rows deleted.
EODA@PROD1> insert into t select * from tmp;
967 rows created.
EODA@PROD1> commit;
Commit complete.
EODA@PROD1> analyze table t compute statistics;
Table analyzed.
EODA@PROD1> select table_name,num_rows,chain_cnt from user_tables where table_name='T';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
T 1000 0
EODA@PROD1> drop table tmp purge;
Table dropped.