这次使用alter table ... move来消除行迁移,如果行迁移经常出现,应该增大pctfree值。
alter table ... move会使索引失效,应该重建索引。
alter table ... move期间不能执行dml。
测试:
SQL> desc t
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER(38)
COL CHAR(2000)
COL2 VARCHAR2(4000)
SQL> alter table t add constraint pk_t primary key(id);
表已更改。
SQL> truncate table t;
表被截断。
SQL> BEGIN
2 FOR i IN 1..20 LOOP
3 INSERT INTO t VALUES(i,'a'||i,'b'||i);
4 END LOOP;
5 COMMIT;
6 END;
7 /
PL/SQL 过程已成功完成。
SQL> create table t_ref(ref_id int ,content varchar(5));
表已创建。
SQL> alter table t_ref add constraint fk_t foreign key(id) references t(id);
alter table t_ref add constraint fk_t foreign key(id) references t(id)
*
第 1 行出现错误:
ORA-00904: "ID": invalid identifier
SQL> alter table t_ref add constraint fk_t foreign key(ref_id) references t(id);
表已更改。
SQL> insert into t_ref values(1,'a');
已创建 1 行。
SQL> insert into t_ref values(2,'a');
已创建 1 行。
SQL> BEGIN
2 FOR i IN 3..20 LOOP
3 INSERT INTO t_ref VALUES(i,'a');
4 END LOOP;
5 COMMIT;
6 END;
7 /
PL/SQL 过程已成功完成。
SQL> select count(*) from t_ref;
COUNT(*)
----------
20
SQL> insert into t_ref values(21,'a');
insert into t_ref values(21,'a')
*
第 1 行出现错误:
ORA-02291: integrity constraint (SYS.FK_T) violated - parent key not found
SQL> create index idx_col2 on t(col2);
索引已创建。
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>true);
PL/SQL 过程已成功完成。
SQL> exec dbms_stats.gather_table_stats(user,'T_REF',cascade=>true);
PL/SQL 过程已成功完成。
SQL> truncate chained_rows;
truncate chained_rows
*
第 1 行出现错误:
ORA-03290: Invalid truncate command - missing CLUSTER or TABLE keyword
SQL> truncate table chained_rows;
表被截断。
SQL> analyze table t list chained rows;
表已分析。
SQL> select * from chained_rows;
未选定行
SQL> update t set col2=lpad('La','2000','*');
已更新20行。
SQL> commit;
提交完成。
SQL> analyze table t list chained rows;
表已分析。
SQL> select t2.owner_name,t2.table_name,t2.head_rowid from chained_rows t2;
OWNER_NAME TABLE_NAME HEAD_ROWID
------------------------------ ------------------------------ ------------------
SYS T AAAMlOAABAAAOraAAB
SYS T AAAMlOAABAAAOrbAAB
SYS T AAAMlOAABAAAOrcAAB
SYS T AAAMlOAABAAAOrdAAB
SYS T AAAMlOAABAAAOreAAB
SYS T AAAMlOAABAAAOrfAAB
已选择6行。
SQL>
SQL> select di.status from dba_constraints di where di.constraint_name='FK_T';
STATUS
--------
ENABLED
SQL> select di.status from dba_constraints di where di.constraint_name='PK_T';
STATUS
--------
ENABLED
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>true);
BEGIN dbms_stats.gather_table_stats(user,'T',cascade=>true); END;
*
第 1 行出现错误:
ORA-20000: index "SYS"."IDX_TID" or partition of such index is in unusable
state
ORA-06512: at "SYS.DBMS_STATS", line 13056
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 1
SQL> select di.status from dba_indexes di where di.index_name='IDX_TID';
STATUS
--------
UNUSABLE
SQL> alter index idx_tid rebuild ;
索引已更改。
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>true);
BEGIN dbms_stats.gather_table_stats(user,'T',cascade=>true); END;
*
第 1 行出现错误:
ORA-20000: index "SYS"."IDX_COL2" or partition of such index is in unusable
state
ORA-06512: at "SYS.DBMS_STATS", line 13056
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 1
SQL> alter index idx_col2 rebuild nologging;
索引已更改。
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade=>true);
PL/SQL 过程已成功完成。
SQL> truncate table chained_rows;
表被截断。
SQL> analyze table t list chained rows;
表已分析。
SQL> select t2.owner_name,t2.table_name,t2.head_rowid from chained_rows t2;
未选定行
alter table ... move会使索引失效,应该重建索引。
alter table ... move期间不能执行dml。