Chinaunix首页 | 论坛 | 博客
  • 博客访问: 99167
  • 博文数量: 23
  • 博客积分: 1583
  • 博客等级: 上尉
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 00:49
文章分类

全部博文(23)

文章存档

2011年(2)

2010年(21)

分类: Oracle

2010-09-10 20:04:12

oracle行链接测试(一)
本实验是验证什么情况下插数据会产生行链接:
先建一个表空间,因为我的数据库的db_block_size是8K,所以我创建的表有五个字段,每个占2000个字节,
这样一行记录大约10K,就能超过一个block的大小了。
SQL> create tablespace test datafile 'test.dbf' size 5m;

Tablespace created.
SQL> create table test (a char(2000),b char(2000),c char(2000),d char(2000),e char(2000)) tablespace test;

Table created.
SQL> insert into test(a) values('test');

1 row created.

SQL> commit;

Commit complete.

SQL>
SQL> select pct_free,table_name from dba_tables where table_name='TEST';

  PCT_FREE TABLE_NAME
---------- ------------------------------
        10 TEST

SQL> select rowid from test;

ROWID
------------------
AAAMwGAAGAAAAAPAAA

SQL>  select dbms_rowid.rowid_object('AAAMwEAAGAAAAAPAAA') data_object_id#,
  2    dbms_rowid.rowid_relative_fno('AAAMwEAAGAAAAAPAAA') rfile#,
  3    dbms_rowid.rowid_block_number('AAAMwEAAGAAAAAPAAA') block#,
  4    dbms_rowid.rowid_row_number('AAAMwEAAGAAAAAPAAA') row# from dual;

DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
--------------- ---------- ---------- ----------
          52228          6         15          0
此时相当于插入了2k的数据了,一个数据块8k,pct_free为10%,除去数据块头的容量,这个块还剩大约5k的可用空间
记录这行所在的block,并dump出来:

SQL> alter system dump datafile 6 block 15;

System altered.

SQL> !
[oracle@oracle1 udump]$ strings ora10_ora_30161.trc|grep nrid
[oracle@oracle1 udump]$
nrid:对于行链接或者行迁移来说的下一个rowid的值。所以现在没产生行迁移或者行链接
然后再插入大约6k数据,
SQL> insert into test(a,b,c) values('test1','test1','test1');

1 row created.

SQL> commit;

Commit complete.

SQL> select dbms_rowid.rowid_block_number(rowid) from test;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
                                  15
                                  16

SQL>
这里可以看出,分配了新块,看看有没有产生行链接?

SQL> alter system dump datafile 6 block 15;

System altered.

SQL> !
[oracle@oracle1 udump]$ strings ora10_ora_30161.trc|grep nrid
[oracle@oracle1 udump]$
由此可知没产生行链接。然后我们看看这行数据到底放在哪个块上了?
SQL> select rowid from test;

ROWID
------------------
AAAMwGAAGAAAAAPAAA
AAAMwGAAGAAAAAQAAA

SQL>  select dbms_rowid.rowid_object('AAAMwEAAGAAAAAQAAA') data_object_id#,
  2    dbms_rowid.rowid_relative_fno('AAAMwEAAGAAAAAQAAA') rfile#,
  3    dbms_rowid.rowid_block_number('AAAMwEAAGAAAAAQAAA') block#,
  4    dbms_rowid.rowid_row_number('AAAMwEAAGAAAAAQAAA') row# from dual;

DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
--------------- ---------- ---------- ----------
          52228          6         16          0

SQL>
虽然15号块还有大约5k的容量,数据却并没放到这个块里
也就是说,新插入的6k的数据全部放到16号块里面去了
所以,这里的结论是,当一个块的剩余空间不够容纳新的一行数据时,而一个新块能容纳这行数据时,
oracle会分配一个新块来放这个数据,而不是将一行数据放到一个块的剩余空间里面
,放不下的部分再放到一个新块里面。
下面再测试下,如果有一个块有剩余空间,又插入一行数据,
但是新块的容量也不够容纳新插入的这行数据的情况 

SQL> truncate table test;

Table truncated.

SQL> select rowid from test;   

no rows selected

SQL> insert into test(a) values('test');

1 row created.

SQL> commit;

Commit complete.

SQL> select rowid from test;

ROWID
------------------
AAAMwFAAGAAAAAPAAA

SQL> select dbms_rowid.rowid_object('AAAMwEAAGAAAAAPAAA') data_object_id#,
  2  dbms_rowid.rowid_relative_fno('AAAMwEAAGAAAAAPAAA') rfile#,
  3  dbms_rowid.rowid_block_number('AAAMwEAAGAAAAAPAAA') block#,
  4  dbms_rowid.rowid_row_number('AAAMwEAAGAAAAAPAAA') row# from dual;

DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
--------------- ---------- ---------- ----------
          52228          6         15          0

SQL> alter system dump datafile 6 block 15;

System altered.

SQL> !
[oracle@oracle1 udump]$ strings ora10_ora_30161.trc |grep nrid
[oracle@oracle1 udump]$
此时没有行链接,继续插入一个连新块也无法全部容纳的行
SQL> insert into test values('ddd','ddd','ddd','ddd','ddd');

1 row created.

SQL> commit;

Commit complete.

SQL> select rowid from test;

ROWID
------------------
AAAMwFAAGAAAAAPAAA
AAAMwFAAGAAAAAPAAB

SQL> select dbms_rowid.rowid_object('AAAMwEAAGAAAAAPAAB') data_object_id#,
  2  dbms_rowid.rowid_relative_fno('AAAMwEAAGAAAAAPAAB') rfile#,
  3  dbms_rowid.rowid_block_number('AAAMwEAAGAAAAAPAAB') block#,
  4  dbms_rowid.rowid_row_number('AAAMwEAAGAAAAAPAAB') row# from dual;

DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
--------------- ---------- ---------- ----------
          52228          6         15          1

SQL> alter system dump datafile 6 block 15;

System altered.

SQL> !
[oracle@oracle1 udump]$ strings ora10_ora_30161.trc |grep nrid
nrid:  0x01800010.0
[oracle@oracle1 udump]$
此时产生了行链接, 所以在这种情况下,这行数据会放到这个有剩余空间的块里面,然后会产生行链接,
由此看来,oracle还是很智能,放到剩余空间里会产生行链接,放到新块里面还是会产生行链接,所以,
干脆放到另外块的剩余空间里面,这个试验现在没测试放不下的那个部分的数据,是放在了新块里面,
还是放在了其他块的剩余空间里面.那部分数据到底链接到哪个块上去了呢?下次再做做实验。。以上测试
如果有问题,请大侠指教

阅读(1482) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~