Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1142439
  • 博文数量: 231
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 2662
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-03 16:35
个人简介

学无止境

文章分类

全部博文(231)

文章存档

2014年(7)

2013年(103)

2011年(11)

2010年(53)

2009年(57)

分类: Oracle

2010-05-19 17:50:21

介绍
-----
本文讨论了行链和行迁移的区别。以及如何检查该情况和解决该问题。
 
概念
-----
当表中某行的数据太大,不适合在单个数据块中,会发生2种情况,行链接或者行迁移。
 
行链接
-------
当行第一次insert到数据块中,单行数据比数据块大,Oracle在段中以链接形式保存行在数据块(1个或多个)中,行链接经常发生在大行中,如行中包含了LONG、LONG RAW,LOB字段等。行链接在这些情况中不可避免。

行迁移
-------
当某行原先是在数据块中是合适的,但update之后,行的总长增加,而块的空闲空间已满。这种情况,Oracle将整行迁移到新的数据块中,Oracle保留行迁移之前的位置,在原始位置指向新的数据块,这样行迁移之后,rowid没有改变。
当发生行链接或行迁移时,关于该行的性能将受到影响,因为Oracle必须扫描更多的数据块来获得行。
 
INSERT和UPDATE语句造成行迁移或行链接时,性能会变差,因为需要额外的操作。
SELECT使用索引选择行链接或行迁移的行时,需要消耗额外的IO。

检测
-----
通过ANALYZE ... LIST CHAINED ROWS命令可以标识出表或簇中的行迁移和行链接。该命令收集每个迁移行或链接行的信息,并将信息存放在指定的表中。创建存放链接行的表,可以执行脚本UTLCHAIN.SQL。
 
SQL> ANALYZE TABLE scott.emp LIST CHAINED ROWS;
SQL> SELECT * FROM chained_rows;
 
也可以通过v$sysstat视图中的'table fetch continued row'统计来发现链接或迁移行的存在。
SQL> SELECT name, value FROM v$sysstat WHERE name = 'table fetch continued row';
 
NAME                                                                 VALUE
---------------------------------------------------------------- ---------
table fetch continued row                                              308
 
虽然行迁移和行链接不同,但在Oracle内部中描述为同一个。当检测到存在链接或迁移的行时,需要具体分析如何处理。

解析
-----
在多数情况中,链接是不可避免的,有其实表中包含大字段,如LONGS,LOB等。如果在不同的表中都有大量的行链,这些表的平均行长度并不大,可能需要考虑重建数据库,选用更大的数据块。
例如:数据库使用2k的数据块。多个表都有较大的varchar列,这些表的平均行长度大于2k。这意味着,数据库可能存在大量的行链接,因为block太小。使用更大的数据块重建数据库对性能有较大意义。
行迁移通常由于PCTFREE设置得较低引起的,数据块中没有足够的空间用来做update。避免行迁移,可以校正表中PCTFREE的设置,使得有足够的空间用于update。可能需要增大PCTFREE来消除行迁移。在数据块中预留更多的空闲空间,那么行就有更多空间增长。
 
消除行迁移的SQL脚本:
-- Get the name of the table with migrated rows:
ACCEPT table_name PROMPT 'Enter the name of the table with migrated rows: '
-- Clean up from last execution
set echo off
DROP TABLE migrated_rows;
DROP TABLE chained_rows;
-- Create the CHAINED_ROWS table
@$ORACLE_HOME/rdbms/admin/utlchain.sql
set echo on
spool fix_mig
-- List the chained and migrated rows
ANALYZE TABLE &table_name LIST CHAINED ROWS;
-- Copy the chained/migrated rows to another table
create table migrated_rows as
  SELECT orig.*
  FROM &table_name orig, chained_rows cr
  WHERE orig.rowid = cr.head_rowid
    AND cr.table_name = upper('&table_name');
 
-- Delete the chained/migrated rows from the original table
DELETE FROM &table_name WHERE rowid IN (SELECT head_rowid FROM chained_rows);
-- Copy the chained/migrated rows back into the original table
INSERT INTO &table_name SELECT * FROM migrated_rows;
spool off

其他消除行迁移的方法:
- alter table move command
- table level export / import
需要注意这些方法需要rebuild整张表,其上的索引可能会失效,需要重建。

注意
-----
当执行文档中清理行链接的脚本时,如果表中包含long row字段,脚本可能会报错:ORA-997: Illegal use of LONG datatype。该错误是正常的,因为CTAS(Create Table As Select)操作不允许包含long raws。所以在包含long raw字段类型的表中,行链接是不可避免的。
 
阅读(908) | 评论(0) | 转发(0) |
0

上一篇:持久表空间中的临时段

下一篇:CheckPoint

给主人留下些什么吧!~~