首页 > 数据库 > Oracle > 正文
1.1.2 系统管理区大小
2015-04-01 14:48:51     我来说两句      
收藏    我要投稿

刚才介绍了统一区大小,并且测试了区的分配规则。在系统管理区中,区的分配规则是一样的,但是,区大小的设定不再由人为决定,Oracle会根据表大小自动设置。

Oracle如何设定区大小呢?只需要创建一个表空间,并进行很简单的测试,就能搞明白这点。命令如下所示:

create tablespace tbs_ts2 datafile '/u01/Disk1/tbs_ts2_01.dbf' size 50m reuse;

上面的命令创建了一个tbs_ts2表空间,至于区大小的管理方式,这里没有指定,这样Oracle默认创建的,就会是系统管理区的大小。

现在在tbs_ts2中创建表,并观察它的区大小。
 

SQL> create table table_lhb1(id int,name varchar2(20)) tablespace tbs_ts2;
Table created.

SQL> select extent_id, file_id, block_id, blocks from dba_extents where segment_
name='TABLE_LHB1' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          5        128          8
可以看到TABLE_LHB1目前有一个区,大小只有8个块,也就是64KB。插入一些数据,将表撑大点再观察。
SQL> insert into table_lhb1 select rownum,'aaa' from dba_objects;

12650 rows created.

SQL> select extent_id, file_id, block_id, blocks from dba_extents where segment_
name='TABLE_LHB1' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          5        128          8
         1          5        136          8
         2          5        144          8
         3          5        152          8
上面向表中插入了12650行,表目前涉及4个区,每个区都是8个块64KB。提交后继续插入,命令如下:
SQL> insert into table_lhb1 select * from table_lhb1;

12650 rows created.

SQL> insert into table_lhb1 select * from table_lhb1;
25300 rows created.

SQL> insert into table_lhb1 select * from table_lhb1;

50600 rows created.

SQL> insert into table_lhb1 select * from table_lhb1;

101200 rows created.

SQL> commit;

Commit complete.

SQL> select extent_id, file_id, block_id, blocks from dba_extents where segment_
name='TABLE_LHB1' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          5        128          8
         1          5        136          8
         2          5        144          8
         3          5        152          8
         4          5        160          8
         5          5        168          8
         6          5        176          8
         7          5        184          8
         8          5        192          8
         9          5        200          8
        10          5        208          8
        11          5        216          8
        12          5        224          8
        13          5        232          8
        14          5        240          8
        15          5        248          8
        16          5        256        128
        17          5        384        128

18 rows selected.

多次插入后,表已经占了很多空间,我们来看一下现在区的使用情况。0~15号区,大小为8个块64KB,从第16号区开始,区大小变为了128个块1MB大小。也就是说,表的大小小于1MB时,表的每个区都是64KB,当表的大小超过1MB,再分配新区时,区的大小将是1MB。读者可以继续测试,当表进一步变大,区大小将会变成8MB,表继续扩大,更大的区也有,这里就不测了。

可见,在系统管理区大小表空间中,区的大小随表的增大而增大。

到这里,我们已经发现了系统管理区大小的秘密。很简单吧?有时候探索Oracle也不是件复杂的事情,只要多动手就行了。我在做培训的时候,也常跟学员讲:探索的过程,就是熟悉Oracle的过程。你探索出的结果不一定很有用,但探索的过程,会加深对Oracle的熟悉程度,这才是研究、探索Oracle的真正目的。研究Oracle,很多时候结果不是目的,过程更有意义。

我们已经了解了统一区大小和系统管理区大小的不同,那么,什么时候使用统一区大小,什么时候使用系统管理区大小呢?

从空间的利用率上讲,小区节省空间,大区可能会浪费空间。比如,当区大小是10MB时,为一个表分配了一个10MB的区,哪怕它只使用了这10MB中的1个字节,这10MB空间也完全属于这个表了,其他表无法再使用这部分空间。从这个角度上讲,小区的空间利用率无疑是高的。

但从性能角度上讲,对于随机访问,大区、小区没有影响。但对于全表扫描这样的操作,大区又是更合适的。因为连续空间更多,可以减少磁头在区间的定位。

在系统管理区大小的方式下,当表比较小时,区也比较小,当表大时,区也随之变大,这种方式无疑可以在空间的利用率、全扫描的性能之间找到一种平衡。因此建议大多数情况下,都可以采用系统管理区大小的方式。除非有某个表,已明确地知道它会很大,为了保证全扫描的性能,直接建一个统一区大小,并且区比较大的表空间,以便将表存放其中。

如果使用统一区大小,几百KB甚至1MB的区,都有点小。其实可以参考系统管理型的表空间,当段的大小超过64MB时,区大小为8MB。在使用统一区大小时,也可以将所有区都固定为8MB。

我见到过很多数据库都使用统一区大小,而且其大小为1MB。原因是在大部分的操作系统中,一次I/O操作的最大的读、写数据量是1MB。即使使用8MB的区,一个区也必须分8次进行I/O操作,超过1MB的区大小,并不能减少I/O操作的次数。

但是,我们要考虑一点,8MB的区连续的空间更多。读取8MB内的第1MB和第2MB数据虽然必须要分两次I/O操作,但这两次I/O操作很可能是连续I/O,因为第1MB和第2MB数据有可能是相连的。如果区大小仅为1MB,虽然读取表的第1区和第2区也是两次I/O操作,但这两次I/O操作很可能不相连,是随机I/O操作。连续I/O操作的性能当然比随机I/O操作的要高。

因此,出于全表扫描性能的考虑,即使使用统一区大小,大点的区(如8MB大小)是很合适的选择。

还有一个问题,不知道大家有没考虑到。这个问题涉及统一区大小表空间的位图块。每个二进制位对应一个区的使用情况,这是没问题的,但系统管理区大小呢?就比如刚才创建的TABLE_LHB1表,前16个区大小为64KB,之后的区大小为1MB。区的大小不同,如何用二进制位来反映区的使用情况呢?

Oracle的处理方法是这样的,以64KB(也就是8个块)为准,每个二进制位对应64KB。1MB的区,对应16个二进制位。每分配一个1MB的区,Oracle将对应的16个二进制位(也就是两个字节)设置为1。释放一个区也同样,将16个二进制位设置为0。这样就解决了区大小不统一的问题,Oracle的解决方法还是很巧妙的!

点击复制链接 与好友分享!回本站首页
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.1.1 统一区大小表空间和区的使用规则
下一篇:1.1.3 碎片:少到可以忽略的问题
相关文章
图文推荐
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站