oracle行链接测试(一)
时间:2010-09-10 来源:tanyangxf
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还是很智能,放到剩余空间里会产生行链接,放到新块里面还是会产生行链接,所以,
干脆放到另外块的剩余空间里面,这个试验现在没测试放不下的那个部分的数据,是放在了新块里面,
还是放在了其他块的剩余空间里面.那部分数据到底链接到哪个块上去了呢?下次再做做实验。。以上测试
如果有问题,请大侠指教
本实验是验证什么情况下插数据会产生行链接:
先建一个表空间,因为我的数据库的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还是很智能,放到剩余空间里会产生行链接,放到新块里面还是会产生行链接,所以,
干脆放到另外块的剩余空间里面,这个试验现在没测试放不下的那个部分的数据,是放在了新块里面,
还是放在了其他块的剩余空间里面.那部分数据到底链接到哪个块上去了呢?下次再做做实验。。以上测试
如果有问题,请大侠指教
相关阅读 更多 +