欢迎投稿

今日深度:

Oracle中行迁移和行链接的清除及检测(1)

Oracle中行迁移和行链接的清除及检测(1)


一、行迁移和行链接的介绍

在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起Oracle数据库性能较低的原因是多方面的,我们能够通过一些正确的设计和诊断来尽量的避免一些Oracle数据库性能不好,Row Migration (行迁移) & Row Chaining (行链接)就是其中我们可以尽量避免的引起Oracle数据库性能低下的潜在问题。通过合理的诊断行迁移和行链接,我们可以较大幅度上提高Oracle数据库的性能。

那究竟什么是行迁移和行链接呢,先让我们从Oracle的block开始谈起。

操作系统的最小读写操作单元是操作系统的block,所以当创建一个Oracle数据库的时候我们应该讲数据库的block size设置成为操作系统的block size的整数倍,Oracle block是Oracle数据库中读写操作的最小单元,Oracle9i之前的Oracle数据库版本中Oracle block一旦在创建数据库的时候被设定后就没法再更改。为了在创建数据库之前确定一个合理的Oracle block的大小,我们需要考虑一些因素,例如数据库本身的大小以及并发事务的数量等。使用一个合适的Oracle block大小对于数据库的调优是非常重要的。

一个Oracle block由三个部分组成,分别是数据块头、自由空间、实际数据三部份组成。

◆数据块头:主要包含有数据块地址的一些基本信息和段的类型,以及表和包含有数据的实际行的地址。
◆自由空间:是指可以为以后的更新和插入操作分配的空间,大小由PCTFREE和PCTUSED两个参数影响。
◆实际数据:是指在行内存储的实际数据。

当创建或者更改任何表和索引的时候,Oracle在空间控制方面使用两个存储参数:

◆PCTFREE:为将来更新已经存在的数据预留空间的百分比。
◆PCTUSED:用于为插入一新行数据的最小空间的百分比。这个值决定了块的可用状态。可用的块时可以执行插入的块,不可用状态的块只能执行删除和修改,可用状态的块被放在freelist中。

当表中一行的数据不能在一个数据block中放入的时候,这个时候就会发生两种情况,一种是行链接,另外一种就是行迁移了。

行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下。这种情况下,Oracle将使用链接一个或者多个在这个段中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有LONG、LONG RAW、LOB等数据类型的字段,这种时候行链接是不可避免的会产生的。

当一行记录初始插入的时候事可以存储在一个block中的,由于更新操作导致行长增加了,而block的自由空间已经完全满了,这个时候就产生了行迁移。在这种情况下,Oracle将会迁移整行数据到一个新的block中假设一个block中可以存储下整行数据),Oracle会保留被迁移行的原始指针指向新的存放行数据的block,这就意味着被迁移行的ROW ID是不会改变的。

当发生了行迁移或者行链接,对这行数据操作的性能就会降低,因为Oracle必须要扫描更多的block来获得这行的信息。

下面举例来具体说明行迁移和行链接的产生过程。

先创建一个pctfree为20和pctused为50的测试表:

create table test
col1 char(20),
col2 number)
storage (
pctfree 20
pctused 50);

当插入一条记录的时候,Oracle会在free list中先去寻找一个自由的块,并且将数据插入到这个自由块中。而在free list中存在的自由的块是由pctfree值决定的。初始的空块都是在free list中的,直到块中的自由空间达到pctfree的值,此块就会从free list中移走,而当此块中的使用空间低于pctused的时候,此块又被重新放到free list中。

Oracle使用free list机制可以大大的提高性能,对于每次的插入操作,Oracle只需要查找free list就可以了,而不是去查找所有的block来寻找自由空间。

具体我们通过下面的一个试验来查看行链接和行迁移是如何产生并在数据文件中体现出来的。先查看ALLAN这个表空间的数据文件号,为了便于测试,我只建立了一个数据文件。

SQL> select file_id from dba_data_files where tablespace_name='ALLAN';
FILE_ID
----------
23

创建一个测试表test:

SQL> create table test ( x int primary key,
a char(2000), b char(2000), c char(2000),
d char(2000), e char(2000) ) tablespace allan;

Table created.

因为我的数据库的db_block_size是8K,所以我创建的表有五个字段,每个占2000个字节,这样一行记录大约10K,就能超过一个block的大小了。


www.htsjk.Com true http://www.htsjk.com/shujukukf/17359.html NewsArticle Oracle中行迁移和行链接的清除及检测(1) 一、行迁移和行链接的介绍 在实际的工作中我们经常会碰到一些Oracle数据库性能较低的问题,当然,引起Oracle数据库性能较低的原因是多方面的...
评论暂时关闭