模拟Oracle行迁移和行链接

行链接
消除方法创建大的block块
------------------ 参考tom kyte的例子--------------------------------------------
--创建4k blocksize的表空间
SQL> alter system set db_4k_cache_size=1m scope=both;

System altered.
SQL> create tablespace tbs1 datafile ‘/u01/app/oracle/oradata/test/tbs_1.dbf‘ size 100m blocksize 4k;

Tablespace created.
--行链接测试
--使用定列宽的char类型来创建行链接测试表
SQL> create table row_chain_demo(
x int primary key,
a char(1000),
b char(1000),
c char(1000),
d char(1000)
) tablespace tbs1;

Table created.
--插入数据
SQL> insert into row_chain_demo(x,a,b,c,d) values(1,‘a‘,‘b‘,‘c‘,‘d‘);

1 row created.

SQL> commit;

Commit complete
--分析测试表,检查行链接
--首先建chaind_rows相关表
SQL> @?/rdbms/admin/utlchain.sql

Table created.
--分析表
SQL> analyze table row_chain_demo list chained rows into chained_rows;

Table analyzed.
--查询行链接
SQL> select * from chained_rows where table_name=‘ROW_CHAIN_DEMO‘;

OWNER_NAME TABLE_NAME CLUSTER_NAME PARTITION_NAME SUBPARTITION_NAME HEAD_ROWID ANALYZE_T
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------ ---------
SYS ROW_CHAIN_DEMO N/A AAAFytAAGAAAAEIAAA 20-AUG-18
记录下此时的执行计划:
SQL> set autotrace traceonly statistics
SQL> set linesize 100
SQL> select /*+index(ROW_CHAIN_DEMO,x)*/* from ROW_CHAIN_DEMO where x=1;

Statistics
----------------------------------------------------------
6 recursive calls
0 db block gets
13 consistent gets
0 physical reads
0 redo size
4815 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
--找出row_chain_demo这张表所对应的数据块
SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from row_chain_demo;

FILE# BLOCK#
---------- ----------
6 264
--dump该数据块进行分析
SQL> alter system dump datafile 6 block 264;

System altered.

--以下为trace文件的内容
data_block_dump,data header at 0x7f28ca793264
===============
tsiz: 0xf98
hsiz: 0x14
pbl: 0x7f28ca793264
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0xba1
avsp=0xb8d
tosp=0xb8d
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0xba1
block_row_dump:
tab 0, row 0, @0xba1
tl: 1015 fb: --H-F lb: 0x1 cc: 2
--正常的行记录为--H-FL--,而这里为只有F(fisrt)而没有L(last),说明在这个数据块中只有行的开始,而没有行的结束,同样cc为2说明这个块中只包含了表的两个列 */
nrid: 0x01c00105.0
-- nrid表示数据块的下一个指针,即其他列数据存放的数据块地址
--通过bbed分析
BBED> p kdbr
sb2 kdbr[0] @118 2977

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0] @3077 0x28

BBED> x /rnccccccc
rowdata[0] @3077
----------
flag@3077: 0x28 (KDRHFF, KDRHFH)
lock@3078: 0x01
cols@3079: 2 --从这也可以看出数据块中只有表的两个列
nrid@3080:0x01c00105.0

col 0[2] @3086: 1
col 1[1000] @3089: a
--消除行链接
--创建blocksize为32的表空间,并将测试表移动到该表空间
SQL> alter system set db_32k_cache_size=1m scope=both;

System altered.

SQL> create tablespace tbs2 datafile ‘/u01/app/oracle/oradata/test/tbs2.dbf‘ size 100m blocksize 32k;

Tablespace created.

SQL> alter table row_chain_demo move tablespace tbs2;

Table altered.
SQL> select index_name from dba_indexes where table_name=‘ROW_CHAIN_DEMO‘;

INDEX_NAME
------------------------------
SYS_C0010231
SQL> alter index SYS_C0010231 rebuild;

Index altered.
--检查行链接
SQL> delete from chained_rows;

1 row deleted.

SQL> commit;

Commit complete.
SQL> analyze table ROW_CHAIN_DEMO list chained rows into chained_rows;

Table analyzed.

SQL> select * from chained_rows where table_name=‘CHAIN_ROW_DEMO‘;

no rows selected
--查看消除行链接后的执行计划状态
SQL> select /*+index(ROW_CHAIN_DEMO,x)*/* from ROW_CHAIN_DEMO where x=1;

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
4668 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)http://write.blog.csdn.net/postedit/52963389
1 rows processed

--可以看出只发生了两次一致性读

行迁移
消除方法,重建数据表
--创建测试表,保证表的字段能够大于blocksize
SQL> create table row_mig_demo(
x int primary key,
a char(1000),
b char(1000),
c char(1000),
d char(1000)
) tablespace tbs1;

Table created.
--插入数据,只插入一个字段的值
SQL> insert into row_mig_demo(x) values(1);

1 row created.

SQL> commit;

Commit complete.
--分析表,查看是否有行迁移情况(此时必然没有)
SQL> analyze table row_mig_demo list chained rows into chained_rows;

Table analyzed.

SQL> select * from chained_rows where table_name=‘ROW_MIG_DEMO‘;

no rows selected
--查看测试表所在的数据块
SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from row_mig_demo;

FILE# BLOCK#
---------- ----------
6 279
--dump数据块查看
SQL> alter system dump datafile 6 block 279;

System altered.
--trace文件内容
data_block_dump,data header at 0x7fa1ea9e1864
===============
tsiz: 0xf98
hsiz: 0x14
pbl: 0x7fa1ea9e1864
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0xf8c
avsp=0xf7b
tosp=0xf7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0xf8c
block_row_dump:
tab 0, row 0, @0xf8c
tl: 6 fb: --H-FL-- lb: 0x1 cc: 1 --FL:说明此时数据行的头和尾都在block内,cc:1,即只有一个字段的数据
col 0: [ 2] c1 02
end_of_block_dump
--通过bbed查看block数据层内容

BBED> p kdbr
sb2 kdbr[0] @118 3980

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0] @4080 0x2c

BBED> x /rnccccccc
rowdata[0] @4080
----------
flag@4080: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@4081: 0x01
cols@4082: 1

col 0[2] @4083: 1
--此时的执行计划状态
SQL> select * from ROW_MIG_DEMO where x=1;

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
639 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
--update测试表,是表的行数据大于blocksize
SQL> update row_mig_demo set a=‘a‘,b=‘b‘,c=‘c‘,d=‘d‘ where x=1;

1 row updated.

SQL> commit;

Commit complete.
SQL> delete from chained_rows;

0 rows deleted.

SQL> commit;

Commit complete.

SQL> analyze table row_mig_demo list chained rows into chained_rows;

Table analyzed.

SQL> select * from chained_rows where table_name=‘ROW_MIG_DEMO‘;

OWNER_NAME TABLE_NAME
------------------------------ ------------------------------
CLUSTER_NAME PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME HEAD_ROWID ANALYZE_T
------------------------------ ------------------ ---------
SYS ROW_MIG_DEMO

N/A AAAVqrAAHAAAAEVAAA 29-OCT-16
--可以看到已经产生了行迁移
--dump数据块查看
SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from row_mig_demo;

FILE# BLOCK#
---------- ----------
6 279 --表所在数据块地址并未改变
SQL> alter system dump datafile 6 block 279;

System altered.

--trace文件内容
data_block_dump,data header at 0x7f28ca793264
===============
tsiz: 0xf98
hsiz: 0x14
pbl: 0x7f28ca793264
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0xba1
avsp=0xb8d
tosp=0xb8d
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0xba1
block_row_dump:
tab 0, row 0, @0xba1
tl: 1015 fb: --H-F--- lb: 0x1 cc: 2
nrid: 0x01c00105.0
col 0: [ 2] c1 02
col 1: [1000]
--bbed查看
BBED> p kdbr
sb2 kdbr[0] @118 2965

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0] @3065 0x28

BBED> x /rnccccccc
rowdata[0] @3065
----------
flag@3065: 0x28 (KDRHFF, KDRHFH)
lock@3066: 0x02
cols@3067: 2
nrid@3068:0x01c00116.0

col 0[2] @3074: 1
col 1[1000] @3077: a
--消除行迁移
SQL> create table row_mig_demp1 as select * from row_mig_demo;

Table created

原文地址:https://www.cnblogs.com/bicewow/p/10558511.html

时间: 2024-11-05 11:25:35

模拟Oracle行迁移和行链接的相关文章

ORACLE 行迁移和行链接

1. 行迁移 当发出update导致记录行长增加,block的剩余空间不足以存放这条记录,就会产生行迁移,发生行迁移时rowid不会改变,原来的block 中会用一个指针存放这条记录在新的block中的地址,发生行迁移会对性能产生影响,因为读这条记录会读两个BLOCK. 行迁移:导致应用需要访问更多的数据块,性能下降. 预防行迁移:1. 将数据块的PCTFREE调大:2. 针对表空间扩大数据块大小 消除行迁移的办法: 创建行迁移表,$ORACLE_HOME/rdbms/admin目录下的utlc

Oracle行迁移和行链接

行迁移和行链接都会导致Oracle性能下降,这篇文章将介绍什么是行迁移和行链接,它们带来的问题,如何来判断它们,并提供了解决它们的办法. 什么是行迁移和行链接 行迁移 Oracle的数据块会保留部分空间供以后更新使用,通常的数据块结构如下: PCTFREE定义一个块保留的空间百分比,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert了,只能被update(具体看下面的PCTFREE介绍). 当一条记录被更新时,数据库引擎首先会尝试在它保存的数据块中寻找足够的空闲空间,如果没有

10、管理数据库存储(行迁移及行连接)

管理数据库存储 1block=8192bytes 案例1:行迁移 1.表中数据如何存储 create table test as select * from hr.employees; create index idx_test on test(employee_id); 只看执行计划,不执行结果. set autotrace traceonly statistics; select * from test where employee_id>0; 强制走索引 select /*+index(t

Oracle 行链接(Row chaining) 与行迁移(Row Migration)

场景:如果VarChar和VarChar2更经常修改,且修改的数据长度每次都不一样,这会引起“行迁移”现象 概念: 行链接(Row chaining) 与行迁移(Row Migration)当一行的数据过长而不能插入一个单个数据块中时,可能发生两种事情:行链接(row chaining)或行迁移(row migration). 行链接当第一次插入行时,由于行太长而不能容纳在一个数据块中时,就会发生行链接.在这种情况下,oracle会使用与该块链接的一块或多块数据块来容纳该行的数据.行连接经常在插

消除行链接、行迁移

行迁移和行链接是经常接触到的一个概念.行链接是记录太大,一个数据块无法存储,oracle就会将其存储在相链接的块中,如果记录中数据类型包括:LONG.LONG RAW.LOB等数据类型时,行链接则无法避免了,可以在AWR实例活动统计部分的table fetch continued row分析可以看出当前数据库中链接行的数量:行迁移是指在update时,数据块已满,记录更新后记录长度增加了,oracle会将整条记录迁移到新的块中,行迁移后ROWID是不变的.参考ID 102989.1消除行链接和行

深入解析SQL Server行迁移记录

总长未超过8060字节,变长和定长列存储在同一页/记录中的记录称为行内数据记录.行内记录最常见了,因为一般的记录长度都是在8060字节内的.行内记录理论上都是存放在一个页面中的,这种记录的结构相对简单,格式也相对固定. 行内记录会包含一些常见数据类型的列,如int.char(n).varchar(n).datetime2.real.money等.这些类型的数据有变长的也有定长的,所以在更新变长列的数据时,会使记录长度增大,到超出空闲空间容量时,这样即使此记录小于8060字节,也会造成此记录在这一

模拟行迁移试验

1.创建scott模式 [[email protected] dbs]$ sqlplus '/as sysdba' SQL*Plus: Release 10.2.0.1.0 - Production on Mon Feb 17 14:59:02 2014 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0

【oracle11g,17】存储结构: 段的类型,数据块(行连接、行迁移,块头),段的管理方式,高水位线

一.段的类型: 1.什么是段:段是存储单元. 1.段的类型有: 表 分区表 簇表 索引 索引组织表(IOT表) 分区索引 临时段 undo段 lob段(blob ,clob) 内嵌表(record类型,table类型) 启动段 :打开数据库时要装入的数据字典系统信息,故在系统表空间内. 注意:smon 回收不用的临时段和undo段. 2.表: 表是存储数据的逻辑单位. 表的功能: 存储.管理数据的基本单元, 表的类型: 普通表:堆表, 例:查询表的行的平均长度 AVG_ROW_LEN 平均长度

Oracle设置列宽,行数

Oracle列宽.行数设置 在命令行进行简单的数据库操作,有时显示出来的数据出现换行情况,为了让数据更加清晰美观,这时可以设置行宽和列宽. 首先设置行数:set pagesize 300(根据个人要求设置); 然后设置列宽:set linesize 200/150(根据个人要求设置); 最后看一下效果,如下: 设置之前 设置之后 这样所有数据显示明了清晰,赶快试一下吧. 原文地址:https://www.cnblogs.com/s1-myblog/p/10888403.html