您的位置:首页 > 其它

设计一个例子,演示PCTUSED和PCTFREE对数据操作的影响

2013-09-10 09:19 369 查看
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资源开销较大,在平时使用时可以根据业务特性结合测试结果灵活设定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐