行迁移和行链接都会导致Oracle性能下降,这篇文章将介绍什么是行迁移和行链接,它们带来的问题,如何来判断它们,并提供了解决它们的办法。
什么是行迁移和行链接
行迁移
Oracle的数据块会保留部分空间供以后更新使用,通常的数据块结构如下:
PCTFREE定义一个块保留的空间百分比,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert了,只能被update(具体看下面的PCTFREE介绍)。
当一条记录被更新时,数据库引擎首先会尝试在它保存的数据块中寻找足够的空闲空间,如果没有足够的空闲空间可用,这条记录将被拆分为两个部分,第一个部分进包括指向第二个部分的rowid,该部分任然保留在原来的数据块中,第二个部分包含所有的具体数据,将保存到另外一个新的数据块中,这个就成为行迁移。
为什么不将整行都放到新的数据块中?
原因是这样会导致该行数据rowid发生变化,而rowid被存储在索引中,也有可能被客户端临时保存在内存中,rowid的变化可能导致查询错误。
PCTFREE介绍
PCTFREE可以在建表的时候指定:
create table test1 pctfree 20 as select rownum as id from all_objects where rownum <= 1000;
这里指定表test1的PCTFREE为20,通过下面的方式可以查看该值:
select table_name, pct_free from user_tables where table_name = 'TEST1';
TABLE_NAMEPCT_FREE
---------------------------
TEST120
在创建了表格后你可以通过alter table来调整PCTFREE值:
alter table test1 pctfree 15;
行链接
行链接和行迁移不同,行链接是当一条记录太大,在一个数据块中无法存入,这时会被拆分为2个或以上的部分,存储在多个块中,这多个块之间会构造一个链,如下:
行迁移是由于更新导致的,而行链接的原因则可能为:
1)直接插入大的记录;
2)更新记录导致记录大于一个数据块,在这时,这样记录可能会同时变为行迁移和行链接。
行迁移和行链接带来的问题
行迁移不会影响全扫描(全扫描更多介绍请看“Oracle性能分析4:数据访问方法之全扫描”),因为第一个部分不包含数据,会被直接跳过;但对于通过rowid进行访问(索引扫描或者直接使用rowid查询),则开销会翻倍,主要由于一次读取需要访问两个块。
行链接则和数据访问方式无关,每次访问到第一个记录片段之后,都需要通过rowid去访问其他的记录片段。
行迁移和行链接也会影响行级锁,因为每个记录片段都需要持有锁,锁的开销和记录片段的个数的增长成正比。
确定行迁移和行链接
确定行迁移和行链接可以使用下面几种方法。
查看v$sysstat和v$sesstat视图
该视图中统计项table fetch continued row可以确认是否出现了行迁移和行链接。
select name,value from v$sysstat where name = 'table fetch continued row';
NAMEVALUE
-----------------------------------------------
table fetch continued row27455
但这个值只能提示你数据库的某个地方存在行迁移或者行链接,如果要评估导致的影响,你需要和table scan rows gotten和table fetch by rowid的统计信息对比。
查看具体表的行迁移和行链接信息
对指定表执行:
analyze table <table_name> list chained rows
如果发现了行链接或者行迁移的记录,它们的rowid就会被记录到CHAINED_ROWS这张表中,该表可以使用$ORACLE_HOME/rdbms/admin目录下的UTLCHAIN.SQL或UTLCHN1.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 urowid,
analyze_timestamp date
);
下面的存储过程将可以用来分析符合条件的所有表:
begin
for obj in (select owner, object_name
from dba_objects
where object_type = 'TABLE'
and <other conditions>) loop
dbms_output.put_line(obj.owner || '.' || obj.object_name);
execute immediate 'analyze table ' || obj.owner || '.' ||
obj.object_name || ' list chained rows';
end loop;
end;
然后通过查看CHAINED_ROWS表中的数据发现哪些表中存在行迁移和行链接:
select table_name,head_rowid from CHAINED_ROWS
TABLE_NAMEHEAD_ROWID
--------------------------------------
IND$AAAAACAABAAAAAdAAA
IND$AAAAACAABAAAAAdAAG
IND$AAAAACAABAAAAAmAAI
IND$AAAAACAABAAAGpRAAH
IND$AAAAACAABAAAN0lAAD
IND$AAAAACAABAAAN0oAAE
......
在这里我们可以看到那些表的那些行存在行迁移和行链接,但并不知道具体是行迁移和行链接,我们可以通过计算记录的长度,再将该长度和块大小进行比较,从而识别出他们具体是行迁移还是行链接。
计算一行的长度使用下面的语句:
select vsize(<col1>) + vsize(<col2>) + ... + vsize(<col3>) from <table> where rowid = '<rowid>';
数据库的块大小在参数db_block_size中保存,参看参数的方法详见“Oracle参数查看方法小结”。
表统计信息中查看行迁移和行链接
表DBA_tables的chain_cnt字段表示行迁移和行链接的数量信息,但dbms_stats包不会收集这个统计信息,该值始终为0。
select table_name,chain_cnt from dba_tables where table_name = 'IND$';
TABLE_NAMECHAIN_CNT
---------------------------
IND$0
通过下面的SQL语句可以收集该信息:
analyze table ind$ compute statistics;
然后再次查看:
select table_name,chain_cnt from dba_tables where table_name = 'IND$';
TABLE_NAMECHAIN_CNT
---------------------------
IND$13
但该方法会导致被分析表的所有对象的统计信息都被覆盖,因此,在实践中不推荐使用。
解决办法
行迁移和行链接的解决办法不同,因此在处理前一定要区分清楚是行迁移还是行链接。
行迁移
首先我们应该避免行迁移,方法是在原块中保留足够的空闲空间,即调整PCTFREE参数值,值的大小需要评估记录扩展的平均大小。
当出现了行迁移后,则只能通过移动数据来解决,具体的方式有:
1)通过导出、导入或者ALTER TABLE MOVE对表进行重整;
2)将迁移的数据复制到临时表中,在原表上删除再重新插入这些数据。
行链接
处理行链接只能增加数据块的大小,但在一些情况下,可以通过将常用字段放在表的前面,不常访问的字段放在表的末尾来提高某些查询的效率(由于Oracle查询时只会取查询相关的字段)。
---------------------
作者:tomato__
来源:CSDN
原文:https://blog.csdn.net/tomato__/article/details/40146573
版权声明:本文为博主原创文章,转载请附上博文链接!
相关推荐
oracle_行链接和行迁移,详细介绍了oracle的行链接和行迁移。
在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起 Oracle数据库性能较低的原因是多方面的,我们能够通过一些...通过合理的诊断行迁移和行链接,我们可以较大幅度上提高Oracle数据库的性能。
当一条记录被更新的时候,数据库引擎首先会尝试在它保存的数据块中寻找足够的空闲空间,如果没有足够的空闲空间可用,这条记录将被...第二部分包含所有的具体数据,将保存到另外一个新的数据块中,这个就成了行迁移。
在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起 Oracle数据库性能较低的原因是多方面的,我们能够通过一些正确的设计和诊断来尽量的避免一些Oracle数据库性能不好,Row Migration (行迁移) ...
本文档详细描述了Oracle数据库中行迁移、行链接的问题:包括概念、原理、产生原因、以及解决方案。
Oracle8i行链接和行迁移探析.pdf
如果你的Oracle数据库性能低下,行链接和行迁移可能是其中的原因之一。我们能够通过合理的设计或调整数据库来阻止这个现象。行链接和行迁移是能够被避免的两个潜在性问题。我们可以通过合理的调整来提高数据库性能。...
NULL 博文链接:https://itstudy123.iteye.com/blog/1024054
5.1.2 段、区间、块和行 142 5.1.3 文件存储技术 144 5.2 创建和管理表空间 146 5.2.1 创建表空间 146 5.2.2 更改表空间 150 5.2.3 删除表空间 154 5.2.4 OMF 154 5.3 管理表空间中的空间 156 5.3.1 区间...
详细介绍了从SQL Server迁移大批量数据到Oracle的方法和具体的操作步骤。
NULL 博文链接:https://noobjava.iteye.com/blog/870011
NULL 博文链接:https://wuhuizhong.iteye.com/blog/2170503
NULL 博文链接:https://zhaoshijie.iteye.com/blog/2201241
NULL 博文链接:https://fuanyu.iteye.com/blog/1402220
5.1.2 段、区间、块和行 142 5.1.3 文件存储技术 144 5.2 创建和管理表空间 146 5.2.1 创建表空间 146 5.2.2 更改表空间 150 5.2.3 删除表空间 154 5.2.4 OMF 154 5.3 管理表空间中的空间 156 5.3.1 区间...
NULL 博文链接:https://1021443917-qq-com.iteye.com/blog/911537
1:包结构 2:多数据源装载配置类; 3:mysql,oracle,sqlserver的声明装载类; 4:实体类,持久层; 5:控制层。
2.1.11 使行链接和行迁移最小化 2.1.12 怎样检测行链接/行迁移 2.1.13 利用脚本检查模式中的链接行 2.1.14 消除行链接 2.1.15 消除行迁移 2.1.16 行链接/行迁移的技巧 2.1.17 怎样定义表的大小 2.1.18 怎样...