当一行的数据过长而不能插入一个单个数据块中时,可能发生两种事情:行链接
(row
chaining)
或行迁移
(row migration)
。
1
、行链接
当第一次插入行时,由于行太长而不能容纳在一个数据块中时,就会发生行链接。在这种
情况下,
Oracle
会使用与该块链接的一块或多块数据块来容纳改行的数据。行链接经常在
插入比较大的数据时才会发生,如包含
long,long row,lob
等类型的数据,这种情况下行
链接是不可避免的。
2
、行迁移
当修改不是行链接的行时,当修改后的长度大于修改前的行长度,并且该数据块中的空闲
空间已经比较小而不能完全容纳该行的数据时,就会发生行迁移。在这种情况下,
Oracle
会将整行的数据迁移到一个新的数据块上,而将该行原先的空间只放一个指针,指向改行
的新位置,而且该行原先空间的剩余空间不再被数据块使用,这些剩余的空间我们将其称
之为空洞,这就是产生表碎片的主要原因,表碎片基本上也是不可避免的,但是我们可以
将其降到一个我们可以接受的程度。注意,即使发生了行迁移,发生了行迁移的行的
rowid
还是不会变化,这也是行迁移会引起数据库
I/O
性能降低的原因。其实行迁移是行
链接的一种特殊形式,但是它的起因和行为和行链接有很大不同,所以一般把它从行链接
中独立出来,单独进行处理。
3
、行链接和行迁移引起数据库性能下降的原因
主要是由于引起多余的
I/O
造成的,当通过索引访问已有行迁移现象的行时,数据库必须
扫描一个以上的数据库才能检索到该行的数据,导致
insert
或
update
时性能较差,因为
需要执行额外的处理。利用索引查询已经链接或迁移的行时,
select
语句的性能比较差,
因为要执行额外的
I/O
。
4
、预防方法
数据块的
pctfree
调大;
针对表空间扩大数据块大小;
评论