在Oracle数据库中表空间是由段组成的而段又是由盘区所组成的通常情况下在大型数据库中合理选择盘区的管理方式能够在很大程度上提高数据库的性能并减轻数据库管理员的工作量笔者对此事深有感触
一盘区的管理方式
在Oracle数据库中盘区主要有两种管理模式分别为目录盘区管理方式和局部盘区管理方式目录盘区管理方式是一种比较老的管理模式在这种管理模式下数据库系统会跟蹤数据目录中的自由和已用盘区并利用递归的SQL语句来修改相关的内容这种盘区管理模式效率比较低现在很版本的 Oracle数据库系统虽然还支持这种管理模式但是不建议使用为此笔者认为除非你现在使用的Oracle数据库系统比较旧只支持目录盘区管理模式否则的话还是采用另外一种管理模式为好
另外一种管理模式就叫做局部盘区管理模式在这种工作模式下主要通过位图来跟蹤盘区从而消除了递归SQL带来的效率低下的问题在 OracleG以后的数据库系统中都支持这种管理模式而且是Oracle数据库推荐使用的管理方式而这种管理方式又可以分为Uniform与 Autoallocate两种其中Uniform是告诉数据库系统利用相同的大小来分配和再分配盘区此时数据库系统在分配盘区的时候都是以固定大小来分配对而Autoallocate选项则是告诉数据库根据实际情况来增量增加盘区的大小如在Windows操作系统上部署Oracle数据库系统其操作系统的块大小一般为KB此时数据库系统在初始化的时候会为刚开始的几个盘区(一般为个盘区)分配比较小的空间如可能只有KB当这个段占用的空间超过这个容量后数据库会再为其分配盘区不过此时分配盘区的大小可能会MB如果还不够还需要增加盘区的话那么这个盘区的大小可能会达到MB甚至更多这种分配方式有什么好处呢?显而易见当段中所含的数据量越大由于后续分配对盘区比较大为此这个段所含总的盘区数量在逐渐减少从而易于管理对数据库性能的提升也有很大的帮助
在选择采取哪种盘区管理方式时笔者如下几个建议可供大家参考
一是一般情况下局部盘区管理方式是数据库管理员的首选除非为了跟以前的数据库兼容或者现在采用的数据库系统不支持这个局部管理方式否则的话笔者强烈建议采用这种盘区管理方式
二是在局部盘区管理方式下有固定盘区与自动分配两种模式此时该如何选择呢?一般来说这要看段所在的表空间的类型如果这个段所在的表空间是临时表空间的话那么段下面的盘区采用Uniform为好如果在数据库中大表空间与小表空间共存的情况下则采用自动分配模式比较好因为自动分配的算法能够让小段持有小盘区而让大段采用大盘区以免数据库拥有太多的盘区所以一般这种管理方式常用在小段与大段共存的一种情况这有助于提升数据库的性能
三是需要注意一些限制的情况如对于撤销表空间来说其是不能够使用局部盘区管理模式下的Uniform管理方式另外虽然局部盘区管理方式与目录盘区管理方式可以利用系统提供的存储过程进行轻松的转换但是其转换仍然受到一定的限制如一般情况下数据库管理员可以将一个持久表空间的管理模式从目录盘区管理方式转换为局部盘区管理方式或者说进行相反的转换但是对于系统表空间和临时表空间来说比较特殊他们只能够从低到高进行转换而不能够从高到低进行转换即指能够将系统表空间或者临时表空间从目录管理模式转换为局部盘区管理方式而不能够进行相反的转换所以对于系统表空间与临时表空间来说在部署之前需要考虑清楚到底采用什么盘区管理方式如果选择局部盘区管理方式的话那么是没有后悔药可吃的因为这两个表空间不能够进行相反的转换
二局部盘区管理方式下的段空间管理方法
笔者之所以推荐使用局部盘区管理方式除了以上所谈的原因外还有一个重要的因素在局部盘区管理方时下在段空间的管理方式下也可以作文章如果采取了局部盘区管理方式的话数据库管理员可以选择是用手工或者自动的段空间管理方式
手工管理段空间的方式主要是为了向后兼容性而保留的在这种管理方式下需要用到三个新的名词分别为自由块列表(可以用来存储数据的块) PCT_FREE(规定块中必须留有的剩余空间以便后续更新块中数据的需要)PCT_USED(规定到块中的使用量达到多少时就不能够再存储数据)这个手工管理方式的主要思路就是盘区中的块不能够全部存储而需要留有一定的剩余空间如此的话如果这个块中的记录需要更改如某个内容从个字符更新到个字符那么更新后的纪录就还保存在同一个块中(因为需要更新的块还有一定的剩余空间)而不会分块保存从而可以提高数据库的性能在每个插入或者更新操作之后数据库系统会比较这个数据块中的剩余自由空间与这个段的PCT_FREE设置如果剩余空间已经不到这个值设置的时候数据库系统就会把这个块从自由块列表中移除如此的话这个块以后就不能够再用来进行插入操作虽然有可能剩余的空间还可以插入一条记录一般情况下只能够进行更新的操作然后再每次更新或者删除操作之后数据库系统同样会检查块中的已用空间与PCT_USED参数进行比较如果更新或者删除操作后块的已用量低于这个参数设置的话系统就会将这个块再放入到自由块列表中后续系统可以对这个块进行插入删除更新等操作这种是数据库系统默认的段空间管理方式但是需要明白一点默认的管理方式并不是说数据库推荐使用这种方式相反在OracleG以后的数据库系统中Oracle官方推荐的是实用自动管理段空间的方式而这里之所以要把手工管理设置为默认主要是为了兼容性的考虑
如果采用自动管理方式的话数据库系统使用位图而不是采用自由列来管理标识哪些数据块可用于插入操作那些块不可用也就是说如果采用自动管理方式的话以上设置的一些参数将会被忽略不过起管理的思路跟上面的是相同的在确定某个块是否可以被进行插入操作时仍然会考虑到纪录的连续性即会为块中数据的更新保留一定的空间在自动管理方式下数据库管理员不用费心的去考虑设置以上两个参数数据库系统会根据实际情况自动进行调节而这个控制的算法好比手工管理方式下复杂的多所以采取字段管理段空间的方式不仅可以减少数据库管理员的工作量而且还可以提高数据库的性能
如果数据库管理员需要采用自动管理方式那么需要注意以下几点
一是默认情况下数据库采用的是手工管理段空间的方式而不是自动管理段空间的方式为此如果数据库管理员想使用自动管理段空间的模式时必须要在建立表空间的时候进行明示如可以通过如下的语句segment space management auto来告诉数据库系统采用自动管理表空间的方式不过在采用这种段空间管理方式的时候需要注意兼容性的问题
二是需要注意某些表空间是不能够使用这种自动管理段空间的方是如默认情况下自动段空间管理方式下不能够用户临时表空间与系统表空间可见临时表空间系统表空撤销表空间在Oracle数据库中有一些比较特殊的限制笔者在这里做一个小的总结对于撤销表空间来说不能够使用局部盘区管理模式下的autoallocate管理方式即不能够采用可变的盘区管理方式而对于临时表空间与系统表空间来说他们不能够使用自动管理段空间的工作模式而且在盘区管理方式上只能够从低级向高级管理方式进行转换而不能够进行相反的转换所以在设置盘区与段空间管理方式的时候这些限制需要引起数据库管理员的重视
不过总的来说笔者推荐使用局部盘区管理方式在这种方式下笔者又推荐可变盘区管理方式(即autoallocate方式)而对于段空间管理来说笔者也建议数据库管理员为持久表空间(系统表空间除外)配制auto方式来管理段空间