行链接和行迁移的秘密

一、概述:
  如果你的Oracle数据库性能低下,行链接和行迁移可能是其中的原因之一。我们能够通过合理的设计或调整数据库来阻止这个现象。
  
  行链接和行迁移是能够被避免的两个潜在性问题。我们可以通过合理的调整来提高数据库性能。本文主要描述的是:
    什么是行迁移与行链接
    如何判断行迁移与行链接
    如何避免行迁移与行链接

  当使用索引读取单行时,行迁移影响OLTP系统。最糟糕的情形是,对所有读取操作而言,增加了额外的I/O。行链接则影响索引读和全表扫描。
  
  注:在翻译行(row)时使用记录来描述(便于理解),如第一行,使用第一条记录。


二、Oralce 块
    操作系统块的大小是操作系统读写的最小操作单元,也是操作系统文件的属性之一。当创建一个数据库时,选择一个基于操作系统块的
  整数倍大小作为Oracle数据库块的大小。Oracle数据库读写操作则是以Oracle块为最小单位,而非操作系统块。一旦设置了Oracle数据块的大小,
  则在整个数据库生命期间不能被更改(除 Oracle 9i之外)。因此为Oracle数据库定制合理的Oralce块大小,象预期数据库总大小以及并发用户数这些
  因素应当予以考虑。 
  数据库块由下列逻辑结构(在整个数据库结构下)

  头部
    头部包含一些常用信息,象块地址,段的类型(表段、索引段等)。也包含一些表、实际数据行的地址信息等。
  
  空闲空间
    用于保留给后续DML(update/insert)操作的空间。通常受pctfree和pctused参数的影响。
  
  数据  
    实际的数据内容
  
  FREELIST, PCTFREE, PCTUSED
    当创建或修改任意表,索引时。Oracle使用两个存储参数来控制空间的分配
    PCTFREE 为已存在数据将来更新需要保留空闲空间的百分比
    PCTUSED 新插入数据可使用空间的最小百分比,该值决定块何时回收到 freelist 结构中
    FREELIST Oracle通过维护该列表来记录或更新所有可用的数据块
  
    Oracle 首先在freelist列表上搜索可用的空闲数据块,搜索成功之后将数据插入到那个空闲块。块在free list 列表中的可用性由pctfree
  参数值来决定。起初一个空块在freelist列表上列出,并且会一直保留,直到到空闲空间达到pctfree设定的值。
  
     当一个块被使用且达到pctfree设定的值之后则该块从freelist列表被移除,而当数据块的可用空间低于PCTUSED值的时候,该块又会回收,
  即重新回到freelist列表。
  
  Oracle使用freelist方式以提高数据库性能。因此,每一个insert 操作,Oracle 仅仅需要搜索freelist结构,而不是搜索所有数据块。


三、行迁移:
    当一个行上的更新操作(原来的数据存在且没有减少)导致当前的数据不能在容纳在当前块,我们需要进行行迁移。一个行迁移意味着整
  行数据将会移动,仅仅保留的是一个转移地址。因此整行数据都被移动,原始的数据块上仅仅保留的是指向新块的一个地址信息。
  
  迁移行不影响全表扫描
    当使用全表扫描时,转移地址被忽略。因为我们最终能够获得所有的数据,所以能够忽略其转移地址。因此行迁移并不会对全表扫描产
    生额外的操作。
  
  迁移行对索引读产生额外的I/O
    当使用索引读取数据时将产生额外的I/O。这是由于索引告诉我们通过文件X,块Y,slot槽Z可以获得该行数据。但是当我们根据地址信息
    达到所在位置时,从其转移地址得知,其真实的数据是存储在文件A,块B,slot槽C上。因此为了寻找该行数据不得不产生额外的逻辑或物理I/O。


四、行链接

    当一行数据太大而不能在一个单数据块容纳时,行链接由此产生。举例来说,当你使用了4kb的Oracle 数据块大小,而你需要插入一行
  数据是8k,Oracle则需要使用3个数据块分成片来存储。因此,引起行链接的情形通常是,表上行记录的大小超出了数据库Oracle块的大小。
  表上使用了LONG 或 LONG RAW数据类型的时候容易产生行链接。其次表上多于255列时Oracle会将这些过宽的表分片而产生行链接。因此,
  与行迁移所不同的是,行迁移是将数据存放到另外一个块,而行链接是数据同时位于多个数据块。

 

     行链接有着不同于行迁移的影响,取决于我们所需的数据。如果我们有一行数据有两个列且跨越两个数据块。假定使用下面的查询:
        SELECT column1 FROM table
      列1位于第一块,它将不会引起任何table fetch continued row 。由于不需要获得第2列的信息,因此行链接没有任何影响。然而,如
    果我们使用下面的查询:
        SELECT column2 FROM table
      由于 column2 在块2且是一个链接行,因此将产生table fetch continued row
  
五、示例样本:


六、演示行迁移 


七、行链接演示



八、如何鉴别行链接和行迁移


九、一个表上链接的行是多少? 


十、列出链接行

  当使用analyze table中的list chained rows子句能够列出一个表上的链接行。该命令的结果是将所有的链接上存储到一个由list chained rows子句
  显示指定的表中。 这些结构有助于决定是否将来有足够的空间实现行更新。
  
  创建CHAINED_ROWS 表
  创建一个用于存储analyze ... list chained rows命令结果的表,可以执行位于$ORACLE_HOME/rdbms/admin目录下的UTLCHAIN.SQL或UTLCHN1.SQL 脚本。
  这个脚本会在当前schema下创建一个名为chained_rows的表
    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
    );

  当chained_rows表创建后,可以使用analyze table命令来指向该表作为输出。


十一、如何避免行链接和行迁移
      增加pctfree能够帮助避免行链接。如果我们为块留下更多的可用空间,则行上有空间满足将来的增长。也可以对那些有较高删除率的表采用重新组织
  或重建表索引来避免行链接与行迁移。如果表上有些行被频繁的删除,则数据块上会有更多的空闲空间。当被插入的行后续扩展,则被插入的行可能会
  分布到那些被删除的行上而仍然没有更多空间来用于扩展。重新组织表则确保主要的空闲空间是完整的空块。
  
      ALTER TABLE ... MOVE 命令允许对一个未分区或分区的表上的数据进行重新分配到一个新的段。也可以分配到一个有配额的不同的表空间。该命令也允许
  你在不能使用alter table的情形下来修改表或分区上的一些存储属性。也可以使用ALTER TABLE ... MOVE 命令中的compress关键字在存储到新段时使用压缩选项。


十二、检测所有表上的行连接与行迁移

  可以通过CHAINED_ROWS 表获取所有表上的行链接与行迁移。 

  通过该方式可以快速的定位一个表上有多少行链接问题的。如果行链接或行迁移较多,则应当基于该表增加pctfree的值 或重建该表。


十三、结论:
   行迁移影响OLTP系统使用索引读取单行。最糟糕的情形所对所有的读都增加额外的I/O。而行链接则影响索引读和全表扫描。
   行迁移通常由update操作引起
   行链接通常有insert操作引起
   基于行链接或行迁移的查询或创建(如索引)由于需要更多的I/O将降低数据库的性能
   调试行链接或行迁移使用analyze 命令,查询v$sysdate视图
   移出行链接或行迁移使用更大的pctfree参数或使用alter table move命令


十四、关于作者

原文链接:The Secrets of Oracle Row Chaining and Migration

Martin Zahn, Akadia AG, Information Technology, CH-3672 Oberdiessbach
EMail: martin dot zahn at akadia dot ch

12.09.2007: Updated for Oracle 10.2


十五、更多参考

关于Oracle数据库中行迁移/行链接的问题

行迁移和行链接的物理存储   
  
  

posted @ 2012-02-17 10:10  生活不是用来挥霍的  阅读(249)  评论(0编辑  收藏  举报