Oracle 行迁移与行链接


行链接和行迁移引起数据库性能下降的原因:
引起性能下降的原因主要是由于引起多余的I/O造成的。当通过索引访问已有行迁移现象的行时,数据库必须扫描一个以上的数据块才能检索到改行的数据。这主要有以下两种表现形式:
1) row migration 或row chaining 导致 INSERT 或 UPDATE语句的性能比较差,因为它们需要执行额外的处理
2) 利用索引查询已经链接或迁移的行的select语句性能比较差,因为它们要执行额外的I/O。

行链接与行迁移的消除
对于行链接只能增大db_block_size来清除。

对于行迁移的清除,一般来说分为两个步骤:第一步,控制住行迁移的增长,使其不在增多,需要设置合理的pctfree参数;第二步,清除掉以前存在的行迁移。

[sql]

  1. --查看行链接或行迁移总体情况   
  2. SQL> SELECT name,value FROM v$sysstat WHERE name like 'table fetch continued row';  
  3.    
  4. NAME                                                                  VALUE  
  5. ---------------------------------------------------------------- ----------   
  6. table fetch continued row                                               519  

如何检测行链接或行迁移

[sql]
  1. --运行utlchain.sql   
  2. SQL> @$Oracle_HOME/rdbms/admin/utlchain.sql    
  3.   
  4. Table created.  
  5.   
  6. --对表进行分析   
  7. SQL> analyze table t list chained rows;    
  8.   
  9. Table analyzed.  
  10.   
  11. --查询chained_rows结果   
  12. SQL> select * from chained_rows;    
  13.   
  14. no rows selected  
测试行迁移,并消除行迁移(CTAS)

[sql]
  1. SQL> desc t  
  2. Name Type           Nullable Default Comments   
  3. ---- -------------- -------- ------- --------    
  4. ID   INTEGER        Y                           
  5. COL  CHAR(2000)     Y                           
  6. COL2 VARCHAR2(4000) Y      
  7.      
  8. SQL> BEGIN  
  9.   2  FOR i IN 1..20 LOOP  
  10.   3    INSERT INTO t VALUES(i,'a'||i,'b'||i);  
  11.   4  END LOOP;  
  12.   5  COMMIT;  
  13.   6  END;  
  14.   7  /  
  15.    
  16. PL/SQL procedure successfully completed  
  17.    
  18. SQL> update t set col2=lpad('La','2000','*');  
  19.    
  20. 20 rows updated  
  21.    
  22. SQL> commit;  
  23.    
  24. Commit complete  
  25.    
  26. SQL> analyze table t list chained rows;  
  27.    
  28. Table analyzed  
  29.    
  30. SQL> select t2.owner_name,t2.table_name,t2.head_rowid from chained_rows t2;  
  31.    
  32. OWNER_NAME                     TABLE_NAME                     HEAD_ROWID  
  33. ------------------------------ ------------------------------ ------------------   
  34. SYS                            T                              AAAMlJAABAAAOraAAB  
  35. SYS                            T                              AAAMlJAABAAAOrbAAB  
  36. SYS                            T                              AAAMlJAABAAAOrcAAB  
  37. SYS                            T                              AAAMlJAABAAAOrdAAB  
  38. SYS                            T                              AAAMlJAABAAAOreAAB  
  39. SYS                            T                              AAAMlJAABAAAOrfAAB  
  40.    
  41. rows selected  
  42.    
  43. SQL> create index idx_tid on t(id);   
  44.    
  45. Index created  
  46.    
  47. SQL> select di.status from dba_indexes di where di.index_name='IDX_TID';  
  48.    
  49. STATUS  
  50. --------   
  51. VALID  
  52.    
  53. SQL> create table t_temp as select * from t where rowid in   
  54.   2  (select cr.head_rowid from chained_rows cr where cr.table_name='T' and cr.owner_name='SYS');  
  55.    
  56. Table created  
  57.    
  58. SQL> select count(*) from t_tmp;  
  59.    
  60. select count(*) from t_tmp  
  61.    
  62. ORA-00942: table or view does not exist  
  63.    
  64. SQL> select count(*) from t_temp;  
  65.    
  66.   COUNT(*)  
  67. ----------   
  68.          6  
  69.   
  70. --当该表被引用时,不能被删除   
  71. SQL> delete from t where rowid in (select cr.head_rowid from chained_rows cr where cr.table_name='T' and cr.owner_name='SYS');  
  72.    
  73. rows deleted  
  74.    
  75. SQL> commit;  
  76.    
  77. Commit complete  
  78.    
  79. SQL> insert into t select * from t_temp;  
  80.    
  81. rows inserted  
  82.    
  83. SQL> select count(*) from t;  
  84.    
  85.   COUNT(*)  
  86. ----------   
  87.         20  
  88.    
  89. SQL> commit;  
  90.    
  91. Commit complete  
  92.    
  93. SQL> select di.status from dba_indexes di where di.index_name='IDX_TID';  
  94.    
  95. STATUS  
  96. --------   
  97. VALID  
  98.     
  99. SQL> truncate table chained_rows;  
  100.    
  101. Table truncated  
  102.   
  103. --重新分析并查看分析结果,分析结果为空,www.bkjia.com说明行迁移已经消除。   
  104. SQL> analyze table t list chained rows;  
  105.    
  106. Table analyzed  
  107.    
  108. SQL> select t2.owner_name,t2.table_name,t2.head_rowid from chained_rows t2;  
  109.    
  110. OWNER_NAME                     TABLE_NAME                     HEAD_ROWID  
  111. ------------------------------ ------------------------------ ------------------   
  112.    
  113. SQL> drop table t_temp;  
  114.    
  115. Table dropped  
  116.   
  117. SQL> select di.status from dba_indexes di where di.index_name='IDX_TID';  
  118.    
  119. STATUS  
  120. --------   
  121. VALID  
  122.    

其实,通过CTAS能够消除的,其实就是行迁移,要消除行链接只能够通过增大块大小来实现。
  • 1
  • 2
  • 下一页

相关内容