解决行迁移实例

行分链与行迁移
----------------
如果经常删除,那么可能不能重用块中的自由空间,所以对于这种情况,我们要利用空间的话,可以把pctused设置高点
主要是在INSERT操作期间引发行分链操作。而行的迁移主要由UPDATE操作引起。
行链接
-- 行链接: Insert or Update引起,一个Row存在不同的block中, 行不同部分通过不同块地址(ROWID)链成一个链,
可以通过设置大的DB_BLOCK_SIZE来减少行链接的发生,但无法避免(LOB)

-- 行迁移: Update引起,由于PCTFREE过小,ROWID未变, 可以通过增大PCTFREE的值减少行迁移的发生

------
行分链是DB_BLOCK_SIZE设置不够大,以至于对于一些大的行(比如varchar2(32666),blob,clob的长度,大于块大小(比如4K))
这样一个块肯定不能保存一行记录,就需要将行分开保存到不同的块中.特别是blob这样的类型,最好设置一个单独的表空间来保存
实际的数据.

包含一个LONG/LONG RAW列时,在这种情况下,后者通常保存在最后Oracle维护一个LOB定位器允许对行外
LOB快速访问。LOB定位器,大约有24个字节大小,DISABLE STORAGE IN ROW参数来实现保存在行外(分散开),
不管数据大小

行分链很难控制(除非通过选择DB_BLOCK_SIZE足够大,可以装下整个行,这通常是不
可能的)。然而,行迁移可以通过CREATE / ALTER TABLE命令的PCTFREE和PCTUSED参数
有效控制。

>>>>>另一种发生行链接是在行迁移不成功的情况下进行的,如UPDATE操作引起。当更新一行使其大小增加
而块中的当前自由空间不足以放下该行,那么就把整个行取出来放到一个有足够空间的块中(如果没有块
有所需的空间放整行,行要分成链;如果即使行分成链仍然没有足够的空间,那么产生一个错误消息
“ORA-1650-55:Unable to extend)

行迁移
-----
我们如果要更新一行(更新总是允许的),并将其行加大,而加大的行所需要的空间大于块中的自由空间时.
假使我们把一行中多出的空间放到另一个块中,而另一行放在原来块中(这就是行分链接),从而使原来块100%的填充.
这样好象只会在单独的行时会发生,ORACLE会把这整行迁移到其他能容纳空间的块中(这就是行迁移).
这样会在原来的块中留一个行头,行头中保留了放实际行的块的地址.对于行链接,但是应用程序
从来不知道这些,使用SQL也没有什么不同,他只是性能上的原因.如果通过索引来读取这行,索引会指向最初的新块
不仅是使用了两个左右的IO读取索引,加上一个IO读取这张表1

通过使用PCTFREE保持每块中的自由空间,允许行仍位于原来的块中,不用管这种扩张。
如果PCTFREE为0,那么所有的自由空间将被INSERT使用,后续的UPDATE将使行迁移到另
外一个块中,以适合扩展的需要。

理想情况下,设置PCTFREE为位于行大小的中间值与最大值之间。例如,如果行大小的中间值估计
为大约900字节,最大的行大小为1255字节,那么设置PCTFREE值在10(缺省)和30之间时是比较合
理的。

--------------------------------------------------------------------------

解决行迁移的实例
SQL> create table CHAINED_TEST (id int,vc varchar2(4000)) tablespace tools pctfree 2 pctused 60;

Table created.

SQL> insert into CHAINED_TEST values (1,'a');

1 row created.

SQL> insert into CHAINED_TEST values (2,'b');

1 row created.

SQL> insert into CHAINED_TEST values (3,'c');


1 row created.

SQL> SQL> insert into CHAINED_TEST values (4,'d');

1 row created.

SQL> commit;

Commit complete.

SQL> exec show_space('CHAINED_TEST',user,'TABLE');
Free Blocks.............................
Total Blocks............................8
Total Bytes.............................65536
Total MBytes............................0
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................11768
Last Used Block.........................8

PL/SQL procedure successfully completed.

SQL> update CHAINED_TEST set vc=rpad('1',3999,'*') where id = 1;

1 row updated.

SQL> update CHAINED_TEST set vc=rpad('2',3999,'*') where id = 2;

1 row updated.

SQL> commit;

Commit complete.

SQL> exec show_space('CHAINED_TEST',user,'TABLE');
Free Blocks.............................
Total Blocks............................8
Total Bytes.............................65536
Total MBytes............................0
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................11768
Last Used Block.........................8

PL/SQL procedure successfully completed.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS;

no rows selected

SQL> update CHAINED_TEST set vc=rpad('3',3999,'*') where id = 3;

1 row updated.

SQL> commit;

Commit complete.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS; --发生行迁移

OWNER_NAME TABLE_NAME
------------------------------ ------------------------------
CLUSTER_NAME PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME HEAD_ROWID ANALYZE_T
------------------------------ ------------------ ---------
CD CHAINED_TEST

N/A AAAFJfAAHAAAC38AAC 09-JUL-04


SQL> exec show_space('CHAINED_TEST',user,'TABLE');
Free Blocks.............................
Total Blocks............................8
Total Bytes.............................65536
Total MBytes............................0
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................11768
Last Used Block.........................8

PL/SQL procedure successfully completed.

SQL> truncate table CHAINED_ROWS;

Table truncated.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS; --表明删除CHAINED_ROWS表后重新分析,迁移没有变

OWNER_NAME TABLE_NAME
------------------------------ ------------------------------
CLUSTER_NAME PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME HEAD_ROWID ANALYZE_T
------------------------------ ------------------ ---------
CD CHAINED_TEST

N/A AAAFJfAAHAAAC38AAC 09-JUL-04


SQL> create table temp as
select * from CHAINED_TEST
where rowid in (select head_rowid
from CHAINED_ROWS
where table_name = 'CHAINED_TEST');
2 3 4 5
Table created.

SQL> delete CHAINED_TEST where rowid in (select head_rowid
from CHAINED_ROWS
where table_name = 'CHAINED_TEST');
2 3
1 row deleted.

SQL> commit;

Commit complete.

SQL> insert into CHAINED_TEST select * from temp; --此时也可以修改CHAINED_TEST表的存储参数

1 row created.

SQL> commit;

Commit complete.

SQL> truncate table CHAINED_ROWS;

Table truncated.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS; --确认行迁移不存在

no rows selected

SQL> exec show_space('CHAINED_TEST',user,'TABLE');
Free Blocks.............................
Total Blocks............................8
Total Bytes.............................65536
Total MBytes............................0
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................11768
Last Used Block.........................8

PL/SQL procedure successfully completed.


move表对行迁移的影响
SQL> drop table CHAINED_TEST;

Table dropped.

SQL> create table CHAINED_TEST (id int,vc varchar2(4000)) tablespace tools pctfree 2 pctused 60;

Table created.

SQL> insert into CHAINED_TEST values (1,'a');

1 row created.

SQL> insert into CHAINED_TEST values (2,'b');

1 row created.

SQL> insert into CHAINED_TEST values (3,'c');

1 row created.

SQL> insert into CHAINED_TEST values (4,'d');

1 row created.

SQL> commit;

Commit complete.

SQL> exec show_space('CHAINED_TEST',user,'TABLE');
Free Blocks.............................
Total Blocks............................8
Total Bytes.............................65536
Total MBytes............................0
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................7
Last Used Ext BlockId...................11768
Last Used Block.........................8

PL/SQL procedure successfully completed.

SQL> update CHAINED_TEST set vc=rpad('1',3999,'*') where id = 1;

1 row updated.

SQL> update CHAINED_TEST set vc=rpad('2',3999,'*') where id = 2;

1 row updated.

SQL> commit;

Commit complete.

SQL> update CHAINED_TEST set vc=rpad('3',3999,'*') where id = 3;

1 row updated.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS;

OWNER_NAME TABLE_NAME
------------------------------ ------------------------------
CLUSTER_NAME PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME HEAD_ROWID ANALYZE_T
------------------------------ ------------------ ---------
CD CHAINED_TEST

N/A AAAFJlAAHAAAC38AAC 09-JUL-04


SQL>
SQL> alter table CHAINED_TEST move tablespace tpcrm;

Table altered.

SQL>
SQL> truncate table CHAINED_ROWS;

Table truncated.

SQL> analyze table CHAINED_TEST list chained rows ;

Table analyzed.

SQL> select * from CHAINED_ROWS; --由此表明move也可以解决行迁移

no rows selected

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23862439/viewspace-1058014/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23862439/viewspace-1058014/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值