科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Oracle中行迁移和行链接的清除及检测(3)

Oracle中行迁移和行链接的清除及检测(3)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文先介绍什么是行迁移和行链接和具体说明行迁移和行链接的产生过程,然后是行迁移和行链接的检测和清除方法。供大家参考!

作者:doorsir 来源:赛迪网技术社区 2007年8月31日

关键字: ORACLE

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共5页)

二、行迁移和行链接的检测

通过前面的介绍我们知道,行链接主要是由于数据库的db_block_size不够大,对于一些大的字段没法在一个block中存储下,从而产生了行链接。对于行链接我们除了增大db_block_size之外没有别的任何办法去避免,但是因为数据库建立后db_block_size是不可改变的(在9i之前),对于Oracle9i的数据库我们可以对不同的表空间指定不同的db_block_size,因此行链接的产生几乎是不可避免的,也没有太多可以调整的地方。行迁移则主要是由于更新表的时候,由于表的pctfree参数设置太小,导致block中没有足够的空间去容纳更新后的记录,从而产生了行迁移。对于行迁移来说就非常有调整的必要了,因为这个是可以调整和控制清除的。

如何检测数据库中存在有了行迁移和行链接呢?我们可以利用Oracle数据库自身提供的脚本utlchain.sql(在$ORACLE_HOME/rdbms/admin目录下)生成chained_rows表,然后利用ANALYZE TABLE table_name LIST CHAINED ROWS INTO chained_rows命令逐个分析表,将分析的结果存入chained_rows表中。从utlchain.sql脚本中我们看到chained_rows的建表脚本,对于分区表,cluster表都是适用的。然后可以使用拼凑语句的办法生成分析所需要的表的脚本,并执行脚本将具体的分析数据放入Chained_rows表中,例如下面是分析一个用户下所有表的脚本:

SPOOL list_migation_rows.sql

SET ECHO OFF

SET HEADING OFF

SELECT 'ANALYZE TABLE ' || table_name ||

' LIST CHAINED ROWS INTO chained_rows;' FROM user_tables;

SPOOL OFF

然后查询chained_rows表,可以具体查看某张表上有多少的行链接和行迁移。

SELECT table_name, count(*) from chained_rows GROUP BY table_name;

当然,也可以查询v$sysstat视图中的’table fetch continued row’列得到当前的行链接和行迁移数量。

SELECT name, value FROM v$sysstat WHERE name = 'table fetch continued row';

可以使用如下的脚本来直接查找存在有行链接和行迁移的表,自动完成所有的分析和统计。

accept owner prompt " Enter the schema name

to check for Row Chaining (RETURN for All): "

prompt

prompt

accept table prompt " Enter the table name

to check (RETURN for All tables owned by &owner): "

prompt

prompt

set head off serverout on term on feed off veri off echo off

!clear

prompt

declare

v_owner varchar2(30);

v_table varchar2(30);

v_chains number;

v_rows number;

v_count number := 0;

sql_stmt varchar2(100);

dynamicCursor INTEGER;

dummy INTEGER;

cursor chains is

select count(*) from chained_rows;

cursor analyze is

select owner, table_name

from sys.dba_tables

where owner like upper('%&owner%')

and table_name like upper('%&table%')

order by table_name;

begin

dbms_output.enable(64000);

open analyze;

fetch analyze into v_owner, v_table;

while analyze%FOUND loop

dynamicCursor := dbms_sql.open_cursor;

sql_stmt := 'analyze table '||v_owner

||'.'||v_table||' list chained rows into chained_rows';

dbms_sql.parse(dynamicCursor, sql_stmt, dbms_sql.native);

dummy := dbms_sql.execute(dynamicCursor);

dbms_sql.close_cursor(dynamicCursor);

open chains;

fetch chains into v_chains;

if (v_chains != 0) then

if (v_count = 0) then

dbms_output.put_line(CHR(9)||CHR(9)||CHR(9)

||'<<<<< Chained Rows Found >>>>>');

v_count := 1;

end if;

dynamicCursor := dbms_sql.open_cursor;

sql_stmt := 'Select count(*) v_rows'||' From '||v_owner||'.'||v_table;

dbms_sql.parse(dynamicCursor, sql_stmt, dbms_sql.native);

dbms_sql.DEFINE_COLUMN(dynamicCursor, 1, v_rows);

dummy := dbms_sql.execute(dynamicCursor);

dummy := dbms_sql.fetch_rows(dynamicCursor);

dbms_sql.COLUMN_VALUE(dynamicCursor, 1, v_rows);

dbms_sql.close_cursor(dynamicCursor);

dbms_output.put_line(v_owner||'.'||v_table);

dbms_output.put_line(CHR(9)||'---> Has '

||v_chains||' Chained Rows and '||v_rows||' Num_Rows in it!');

dynamicCursor := dbms_sql.open_cursor;

sql_stmt := 'truncate table chained_rows';

dbms_sql.parse(dynamicCursor, sql_stmt, dbms_sql.native);

dummy := dbms_sql.execute(dynamicCursor);

dbms_sql.close_cursor(dynamicCursor);

v_chains := 0;

end if;

close chains;

fetch analyze into v_owner, v_table;

end loop;

if (v_count = 0) then

dbms_output.put_line('No Chained Rows found

in the '||v_owner||' owned Tables!');

end if;

close analyze;

end;

/

set feed on head on

prompt


    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章