行连接的处理方式指引

来源:这里教程网 时间:2026-03-03 18:06:45 作者:

    我们的数据库的行连接已经到了一个比较严重的地步了,对awr 报表的统计数据是 sunha5 花在行连接的 i/o 是平均每秒 600 次左右。 通过对产品库和商家进行清理后,目前的统计降到了200 次左右,还有继续下降的空间。   行连接的成因 行连接(chained rows) 是因为对字段做修改后,导致修改后的数据大于原来的数据长度,在现在的行里,已经无法存储这个数据,写不下的数据会被放到别的数据块里,并且在原行中纪录这个地址。这样导致的问题是,如果要读出这个行数据, oracle 必须要进行 2 次甚至多次 i/o 操作才会把整行数据读出来,增加了 i/o 成本,导致性能下降。    Oracle 提供了工具进行行连接的检测: 我们以商家系统的处理为例演示下: 注: 本操作为直接修改线上数据库需要小心执行。   1. 在当前用户下执行 $ORACLE_HOME/rdbms/amdin/utlchain.sql   建立一个表。

    键表语句:

 create table CHAINED_ROWS (

  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

);

 

2. 对要进行分析的表执行分析命令:

analyze table  table_name  list chained rows into CHAINED_ROWS;

 select 'analyze table cyp_app.'||table_name||' list chained rows into CHAINED_ROWS;'  from  dba_tables where owNer='CYP_APP';

 

  生成商家的所有的表的分析语句然后批量执行。

这个分析命令会把表中有行连接的行的rowid 纪录到这个表中。

Select  * from  chained_rows:

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM5yAAJ     07-1 -09

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM51AAU 07-1 -09

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM53AAK 07-1 -09

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM54AAF 07-1 -09

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM56AAG 07-1 -09

CYP_APP ENT_COMPANY_TEXT   N/A AABZKnABNAAAM6AAAH 07-1 -09

 

3. 处理行连接的数据。先备份 ,删除原表的数据,然后再insert

 

drop table tmp_as;

 

-- 建立临时表。

create table  tmp_as as select a.* from  CYP_APP.ENT_QUESTION a where a.rowid in (

select head_rowid from chained_rows where table_name ='ENT_QUESTION');

 

select * from tmp_as ;

 

 

4. 对表进行更新,删除和insert   操作尽量争取在一个事务里完成。如果有外键引用需要先把外键引用禁用掉。

 

   Commit;

 

delete from CYP_APP.ENT_QUESTION where rowid in (

select head_rowid from chained_rows where table_name ='ENT_QUESTION');

 

 insert into  CYP_APP.ENT_QUESTION select * from tmp_as ;

 

Commit;

 

 5. chained_rows 表中删除跟该表相关的纪录  

 

delete from  chained_rows where table_name ='ENT_QUESTION';

 

 6. 如果表的 chained rows 比较多,比如有几万笔纪录或者 10 几万笔纪录,

我们因该考虑修改表的存储参数,把pctfree 参数修改为 15 或者 20

alter table   CYP_APP.ENT_QUESTION    pctfree 15 ;

  7, 如果表的行连接比较多,到了几万笔的数量级,那么对这个表的 update 说明已经进行了很多次的了,

索引估计也会比较大,浪费空间。建议对该表的索引做一个rebuild

  

相关推荐