ITPUB论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1001|回复: 6

insert时堆表数据块写入顺序的问题 [复制链接]

精华贴数
1
技术积分
848
社区积分
3
注册时间
2004-7-24
论坛徽章:
3
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28
发表于 2007-6-30 03:03:08 |显示全部楼层
TOM说,对于堆表数据的插入,数据会被写到最适合的块,而不是以特定的顺序写入。

如下的实验中,测试数据库的块大小为8k,建立一张表,插入3行数据。 第一行大约0.2k,第二行大约8k,第三行大约0.2k。 根据上面的结论,第一行在一个块(快号10)上,第二行由于太大不能在第一个块上放下( 8k + 0.2k > 8k ),将会在第二个块(快号11)写入。 第三行根据上述理论应该写入第一个块( 0.2k + 0.2k < 8k )。 为什么会写入第三个块(快号12)了呢,百思不得其解,谢谢指点


[PHP]
SQL> show parameters db_block_size;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_size                        integer     8192
SQL> create table t ( i number,  a varchar2(4000),  b varchar2(4000) );

Table created.

SQL> insert into t values ( 1, rpad('*',100,'*'), rpad('*',100,'*')  );

1 row created.

SQL> insert into t values ( 2, rpad('*',3900,'1'), rpad('*',3900,'1') );

1 row created.

SQL> insert into t values ( 3, rpad('*',100,'2') , rpad('*',100,'2') );

1 row created.

SQL>
SQL> commit;

Commit complete.

SQL> SELECT ROWID, i, DBMS_ROWID.rowid_object (ROWID) OBJECT,
  2         DBMS_ROWID.rowid_relative_fno (ROWID) file_no,
  3         DBMS_ROWID.rowid_block_number (ROWID) BLOCK,
  4         DBMS_ROWID.rowid_row_number (ROWID) rowno
  5    FROM t;

ROWID                       I     OBJECT    FILE_NO      BLOCK      ROWNO
------------------ ---------- ---------- ---------- ---------- ----------
AAAHjeAAMAAAAAKAAA          1      30942         12         10          0
AAAHjeAAMAAAAALAAA          2      30942         12         11          0
AAAHjeAAMAAAAAMAAA          3      30942         12        12          0





[/PHP]

注册会员

beginner

精华贴数
0
技术积分
3159
社区积分
137
注册时间
2007-4-19
论坛徽章:
11
授权会员
日期:2007-07-08 18:54:592009日食纪念
日期:2009-07-22 09:30:00生肖徽章2007版:蛇
日期:2008-10-24 16:46:512008北京奥运纪念徽章:现代五项
日期:2008-10-24 13:26:49生肖徽章2007版:羊
日期:2008-04-17 18:05:112008新春纪念徽章
日期:2008-02-13 12:43:03生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:鸡
日期:2008-01-02 17:35:53ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44会员2007贡献徽章
日期:2007-09-26 18:42:102010广州亚运会纪念徽章:皮划艇
日期:2011-02-15 13:51:42
发表于 2007-6-30 08:00:44 |显示全部楼层
学习,希望大师们解答!

使用道具 举报

超级版主

人生就是如此

精华贴数
39
技术积分
113462
社区积分
12389
注册时间
2001-12-12
论坛徽章:
80
ITPUB元老
日期:2005-02-28 12:57:00蛋疼蛋
日期:2011-05-27 08:50:45蜘蛛蛋
日期:2011-07-01 08:38:17ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19现任管理团队成员
日期:2011-05-07 01:45:08
发表于 2007-6-30 08:55:31 |显示全部楼层
1:不知道你是不是ASSM 类型的表空间
2:如果不是assm类型表空间,存在这种可能,当block 10 不能被插入一个新的数据的时候将从 freelist中摘掉。 这么大的行我没有测试过,以前我测试过比如block 快达到 (1 -  pctfree) 的时候如果新行不能被插入的时候就从freelist移掉了。

使用道具 举报

精华贴数
1
技术积分
848
社区积分
3
注册时间
2004-7-24
论坛徽章:
3
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28
发表于 2007-6-30 10:50:43 |显示全部楼层
我的不是assm,表空间为SEGMENT SPACE MANAGEMENT MANUAL

那就是当oracle发现第二行不能插入block10的时候,就将blcok10从freelist移掉了。

但是block还有挺大空余空间,这样的话,有点浪费

有什么方法察看这个对象的相关的freelist,然后再看freelist有哪些block呢,谢谢!


大师周末早起替人解惑啊,谢谢:)

使用道具 举报

精华贴数
0
技术积分
1658
社区积分
19
注册时间
2007-3-9
论坛徽章:
4
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44数据库板块每日发贴之星
日期:2007-12-23 01:04:26生肖徽章2007版:兔
日期:2008-01-02 17:35:53生肖徽章2007版:牛
日期:2009-05-05 23:34:11
发表于 2007-7-1 02:42:58 |显示全部楼层
是啊,有这个方法吗,我也想知道

使用道具 举报

超级版主

人生就是如此

精华贴数
39
技术积分
113462
社区积分
12389
注册时间
2001-12-12
论坛徽章:
80
ITPUB元老
日期:2005-02-28 12:57:00蛋疼蛋
日期:2011-05-27 08:50:45蜘蛛蛋
日期:2011-07-01 08:38:17ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19现任管理团队成员
日期:2011-05-07 01:45:08
发表于 2007-7-1 08:43:57 |显示全部楼层
要看的话,你必须得熟悉 block 的结构中关于 freelist 的 link 这部分内容,通过对segment head进行 block  dump 就可以找到link  headr 然后顺着一个个block的找就看到了。

你也可以搜索下有关freelist的文章,有介绍这些内容的。

使用道具 举报

精华贴数
1
技术积分
848
社区积分
3
注册时间
2004-7-24
论坛徽章:
3
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442008新春纪念徽章
日期:2008-02-13 12:43:032009新春纪念徽章
日期:2009-01-04 14:52:28
发表于 2007-7-1 14:07:03 |显示全部楼层
网上看了一些资料,重新作了一下测试,不知道测试过程或者对freelist的理解有什么问题没有.....

[PHP]

SQL> create table t ( i number,  a varchar2(4000),  b varchar2(4000) );

Table created.

SQL> select FILE_ID, block_id, blocks from dba_extents where segment_name = 'T'
AND OWNER = 'SCOTT';

   FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ----------
        12          9          8

SQL> alter system dump datafile 12 block 9;--dump segment header

System altered.

  nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 0
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
End dump data blocks tsn: 13 file#: 12 minblk 9 maxblk 9
-- 根据nfl的值得知,有一个freelist,根据flag的值得知,这个freelist尚未使用


SQL> insert into t values ( 1, rpad('*',100,'*'), rpad('*',100,'*')  );

1 row created.

SQL> SELECT ROWID, i, DBMS_ROWID.rowid_object (ROWID) OBJECT,
  2     DBMS_ROWID.rowid_relative_fno (ROWID) file_no,
  3       DBMS_ROWID.rowid_block_number (ROWID) BLOCK,
  4     DBMS_ROWID.rowid_row_number (ROWID) rowno
  5   FROM t;

ROWID                       I     OBJECT    FILE_NO      BLOCK      ROWNO
------------------ ---------- ---------- ---------- ---------- ----------
AAAHkEAAMAAAAAKAAA          1      30980         12         10          0


SQL> alter system dump datafile 12 block 10;--插入数据位于第10块,dump出来

System altered.

Block header dump:  0x0300000a
Object id on Block? Y
seg/obj: 0x7904  csc: 0x00.55c15a  itc: 2  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
--根据flag的值得知,这个块在freelist上

SQL> alter system dump datafile 12 block 9;

System altered.

alter system dump datafile 12 block 9;
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 1
  SEG LST:: flg: USED   lhd: 0x0300000a ltl: 0x0300000a
End dump data blocks tsn: 13 file#: 12 minblk 9 maxblk 9
--顺便看一下block9, flg标示已经变为USED, lhd的值指向block 10的

SQL> insert into t values ( 2, rpad('*',3900,'1'), rpad('*',3900,'1') );

1 row created.

SQL> SQL> SELECT ROWID
SP2-0734: unknown command beginning "SQL> SELEC..." - rest of line ignored.
SQL>   2     DBMS_ROWI
SQL> SELECT ROWID, i, DBMS_ROWID.rowid_object (ROWID) OBJECT,
  2     DBMS_ROWID.rowid_relative_fno (ROWID) file_no,
  3       DBMS_ROWID.rowid_block_number (ROWID) BLOCK,
  4     DBMS_ROWID.rowid_row_number (ROWID) rowno
  5   FROM t;

ROWID                       I     OBJECT    FILE_NO      BLOCK      ROWNO
------------------ ---------- ---------- ---------- ---------- ----------
AAAHkEAAMAAAAAKAAA          1      30980         12         10          0
AAAHkEAAMAAAAALAAA          2      30980         12         11          0

SQL> alter system dump datafile 12 block 10;

System altered.

alter system dump datafile 12 block 10;
Block header dump:  0x0300000a
Object id on Block? Y
seg/obj: 0x7904  csc: 0x00.55c15a  itc: 2  flg: -  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
--flg的值为"-",表示当插入第二行的时候,block10已经从freelist中移掉。 为什么???block10有超过 8k*pctfree的空间啊?

SQL> alter system dump datafile 12 block 11;

System altered.

Block header dump:  0x0300000b
Object id on Block? Y
seg/obj: 0x7904  csc: 0x00.55c5b5  itc: 2  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
--block11这个时候已经加入freelist

[/PHP]

结论:如biti_rainy所言,如果不是assm类型表空间,存在这种可能block 10 不能被插入一个新的数据的时候将从 freelist中摘掉了。

问题: oracle根据什么算法,将block10丛freelist移除? 不应该啊,因为block10有超过 8k*pctfree的空间啊?

使用道具 举报

相关内容推荐
您需要登录后才可以回帖 登录 | 注册

TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 邮箱 虎吧 老博客 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
CopyRight 1999-2011 itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001 广播电视节目制作经营许可证:编号(京)字第1149号
  
回顶部