PCTUSED和PCTFREE是数据块的存储属性,单位都是%
PCTFREE:表示什么时候不可以再往块中插入数据,但是更新数据和删除数据是可以的。例如 我们设置为20%,当数据块空闲空间剩余20%时候,这个数据块就从空闲列表(free list)中移出,移出后我们就不能再往数据块里面插入数据了。对于数据块中已有数据的更新可以使用数据块中的保留空间,只有当数据块的占用空间比例(PCTUSED)低于40%时才能向其插入新数据。
PCTUSED:表示什么时候可以继续往块中插入数据,例如 我们设置40%,只有当数据块占用容量低于40%时才允许再次插入新数据,此时数据块会插入空闲列表(free list),数据块就能够继续接受新记录,过程如此往复循环。
PCTUSED和PCTFREE二者没有任何关系,各做各的
场景:应用在OLTP系统上多,因为OLTP是一种多事务短时间片操作频繁的系统,设置数据块可以存放多少记录的容量有利于提高系统IO性能
Oracle 10g 11g PCTFREE默认值是10%,设置较高意味着数据块没有被利用多少就从freelist中移出,不利于数据块的充分使用(适合频繁更新的操作)。设置较低意味着更新时候会出现行迁移,从而也会影响Oracle的性能(适合频繁插入的操作)。
PCTUSED默认值是40%,设置较高意味着相对较满的数据块可有效循环使用空闲空间频繁插入,会导致IO资源的消耗较大,设置较低意味着当一个数据块快空的时候才被放入freelist,数据块一次可以插入很多数据,减少IO资源的消耗。
一般这两个值的总和不要大过90,否则会使Oracle将更多的时间花费在处理空间利用率上
实验
LEO1@LEO1> drop table leo4 purge; 清空环境
Table dropped.
LEO1@LEO1> create table leo4 as select * fromdba_objects; 创建一个新的leo4
Table created.
LEO1@LEO1> col table_name for a10
LEO1@LEO1> select table_name,tablespace_name,pct_free,pct_usedfrom user_tables where table_name='LEO4';
TABLE_NAME TABLESPACE_NAME PCT_FREE PCT_USED
---------------------------------------------------------------------------------------------
LEO4 LEO1 10
LEO4表所在的表空间是ASSM段管理方式,在使用位图管理段空间的情况不可定义PCTUSED,只有使用MSSM段管理方式,在字典管理模式下才可调用free list,这2个参数可设置生效。
LEO1@LEO1> select segment_name,blocks,freelists fromdba_segments where segment_name='LEO4';
SEGMENT_NAME BLOCKS FREELISTS
------------ ---------- ----------------------------------------
LEO4 1152
我们创建的leo4表,占用1152个数据块,freelist和freelistgroup在ASSM表空间中根本不存在,仅在MSSM表空间使用这个技术
详细出处参考:http://www.jb51.net/article/32017.htm
LEO1@LEO1> alter table leo4 pctfree 50; 修改pctfree=50
Table altered.
LEO1@LEO1> alter table leo4 pctused 40; 修改pctused=40
Table altered.
LEO1@LEO1> alter table leo4 move tablespacenew_leo1; 把表leo4迁移到new_leo1表空间
Table altered.
new_leo1这个表空间是我之前已经创建好的一个ASSM表空间
语法:createtablespace new_leo1 datafile '/u01/app/oracle/oradata/LEO1/new_leo1.dbf' size20m autoextend off;
LEO1@LEO1> select table_name,tablespace_name,pct_free,pct_usedfrom user_tables where table_name='LEO4';
TABLE_NAME TABLESPACE_NAME PCT_FREE PCT_USED
---------------------------------------------------------------------------------------------
LEO4 NEW_LEO1 50
从这里可以看到leo4表已经从leo1表空间迁移到new_leo1表空间了,pct_free也修改为50,而pct_used在ASSM模型下依然不会生效的,freelist也不会生效。
LEO1@LEO1> select segment_name,blocks,freelists fromdba_segments where segment_name='LEO4';
SEGMENT_NAME BLOCKS FREELISTS
------------ ---------- ----------------------------------------
LEO4 1920
从这里可以看到leo4表占用的块数从1152上升到1920,这就是因为我们修改了pctfree值得结果,原来默认值为10%的时候,我们可以有90%空间插入数据,现在修改成了50%,我们就只能有50%空间插入数据,存放数据的空间比从90%下降到50%,当数据总量不变的情况下,就只有增加数据块的个数来解决了。
下面我们演示PCTUSED参数的影响
①MSSM:由你设置freelists、freelistgroups、pctused、pctfree、initrans等参数来控制如何分配、使用段中的空间
②ASSM:你只需控制一个参数pctfree,其他参数即使建了也将被忽略
LEO1@LEO1> create tablespace mssm_leo1 datafile'/u01/app/oracle/oradata/LEO1/mssm_leo1.dbf' size 50m autoextend off segmentspace management manual;
Tablespace created.
LEO1@LEO1> select tablespace_name,segment_space_management fromuser_tablespaces where tablespace_name in ('LEO1','NEW_LEO1','MSSM_LEO1');
TABLESPACE_NAME SEGMEN
------------------------------ ---------------- ----------------------
LEO1 AUTO
NEW_LEO1 AUTO
MSSM_LEO1 MANUAL
我们创建一个手动段空间管理MSSM的表空间,在上面创建个新表leo5
LEO1@LEO1> drop table leo5 purge; 清理环境
Table dropped.
LEO1@LEO1> create table leo5 tablespace mssm_leo1 as select *from dba_objects;
Table created. 创建表并指定MSSM表空间存储
LEO1@LEO1> selecttable_name,tablespace_name,pct_free,pct_used,freelists,freelist_groups fromuser_tables where table_name='LEO5';
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED FREELISTS FREELIST_GROUPS
--------------------------------------------------------------------------------------------------------------------------
LEO5 MSSM_LEO1 10 40 1 1
此时我们就可以使用上述参数来控制如何分配和使用段中空间了
LEO1@LEO1> select segment_name,blocks,freelists,freelist_groupsfrom dba_segments where segment_name='LEO5';
SEGMENT_NAME BLOCKS FREELISTSFREELIST_GROUPS
------------ ---------- ---------- ----------------------------------- ---------------
LEO5 1152 1 1
LEO1@LEO1> alter table leo5 pctfree 20;
Table altered.
LEO1@LEO1> alter table leo5 pctused 50;
Table altered.
LEO1@LEO1> select segment_name,blocks,freelists,freelist_groupsfrom dba_segments where segment_name='LEO5';
SEGMENT_NAME BLOCKS FREELISTSFREELIST_GROUPS
------------ ---------- ---------- ----------------------------------- ---------------
LEO5 1152 1 1
pctused的变化并不会影响第一次加载的数据,因为原始数据块一开始都是空的,不管如何设置pctused数据都可以顺利加载进来,只对后面的加载会有影响。
LEO1@LEO1> select table_name,tablespace_name,pct_free,pct_used,freelists,freelist_groupsfrom user_tables where table_name='LEO5';
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED FREELISTS FREELIST_GROUPS
--------------------------------------------------------------------------------------------------------------------------
LEO5 MSSM_LEO1 20 50 1 1
我们修改一下pctfree和pctused,可以看到在MSSM段空间管理模式下都是生效的。
LEO1@LEO1> drop table leo6 purge; 清理环境
Table dropped.
LEO1@LEO1> drop table leo7 purge;
Table dropped.
LEO1@LEO1> create table leo6 tablespace mssm_leo1 as select *from dba_objects; 创建leo6表
Table created.
LEO1@LEO1> create table leo7 tablespace mssm_leo1 as select *from dba_objects; 创建leo7表
Table created.
LEO1@LEO1> execute dbms_stats.gather_table_stats(ownname=>'LEO1',tabname=>'LEO6');
PL/SQL procedure successfully completed.
LEO1@LEO1> executedbms_stats.gather_table_stats(ownname=>'LEO1',tabname=>'LEO7');
PL/SQL procedure successfully completed.
进行统计分析收集表存储信息
LEO1@LEO1> selecttable_name,tablespace_name,pct_free,pct_used,blocks,freelists,freelist_groupsfrom user_tables where table_name='LEO6';
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED BLOCKS FREELISTSFREELIST_GROUPS
---------------------------------------------------------------------------------------------------------------------------------------------
LEO6 MSSM_LEO1 10 40 1024 1 1
LEO1@LEO1> selecttable_name,tablespace_name,pct_free,pct_used,blocks,freelists,freelist_groupsfrom user_tables where table_name='LEO7';
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED BLOCKS FREELISTSFREELIST_GROUPS
---------------------------------------------------------------------------------------------------------------------------------------------
LEO7 MSSM_LEO1 10 40 1024 1 1
我们在初始化表时,PCT_FREE=10 PCT_USED=40 BLOCKS=1024,下面我们只修改PCT_USED
LEO1@LEO1> alter table leo6 pctused 30;
Table altered.
LEO1@LEO1> alter table leo7 pctused 60;
Table altered.
LEO1@LEO1> selecttable_name,tablespace_name,pct_free,pct_used,blocks,freelists,freelist_groupsfrom user_tables where table_name in ('LEO6','LEO7');
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED BLOCKS FREELISTSFREELIST_GROUPS
---------------------------------------------------------------------------------------------------------------------------------------------
LEO6 MSSM_LEO1 10 30 1024 1 1
LEO7 MSSM_LEO1 10 60 1024 1 1
已经修改完成,但没有影响数据块分配数量,这是正常的,既然PCT_USED是表示何时该插入的阀值,那么我们可以delete where where object_type in('TABLE','INDEX','VIEW','SEQUENCE');一些记录,降低到阀值的允许范围内,在插入一些记录,设置较高意味着相对较满的数据块可有效循环使用空闲空间频繁插入,此时占用的数据块应该较少,反之较多。
LEO1@LEO1> delete from leo6 where object_type in('TABLE','INDEX','VIEW','SEQUENCE');
11870 rows deleted.
LEO1@LEO1> delete from leo7 where object_type in('TABLE','INDEX','VIEW','SEQUENCE');
11870 rows deleted. 删除11870行
LEO1@LEO1> insert into leo6 select * from leo5;
71969 rows created.
LEO1@LEO1> insert into leo7 select * from leo5;
71969 rows created. 插入71969行
LEO1@LEO1> executedbms_stats.gather_table_stats(ownname=>'LEO1',tabname=>'LEO6');
PL/SQL procedure successfully completed.
LEO1@LEO1> executedbms_stats.gather_table_stats(ownname=>'LEO1',tabname=>'LEO7');
PL/SQL procedure successfully completed.
LEO1@LEO1> select table_name,tablespace_name,pct_free,pct_used,blocks,freelists,freelist_groupsfrom user_tables where table_name in ('LEO6','LEO7');
TABLE_NAME TABLESPACE_N PCT_FREE PCT_USED BLOCKS FREELISTSFREELIST_GROUPS
---------------------------------------------------------------------------------------------------------------------------------------------
LEO6 MSSM_LEO1 10 30 1959 1 1
LEO7 MSSM_LEO1 10 60 1901 1 1
小结: leo7 占用数据块比 leo6 少,是因为当后续加载数据时, Oracle 会根据 PCT_USED 参数动态调节数据块何时可以继续插入数据,当删除后阀值降到了 60% 以下就可以往 leo7 表中的块插入数据,当删除后阀值降到了 30% 以下才可以往 leo6 表中的块插入数据,由此看来, leo7 中的块利用率较高,但 IO 资源开销较大,在平时使用时可以根据业务特性结合测试结果灵活设定。