现在的位置: 首页 > 综合 > 正文

不同的pctfree-pctused占用的BLOCK不同的示例

2014年03月09日 ⁄ 综合 ⁄ 共 5263字 ⁄ 字号 评论关闭

PCTFREE和PCTUSED作用及举例

PCTFREE的作用是:当数据块的剩余容量达到PCTFREE值时,此数据块不再被记录于freelist中,不允许其他数据再存放至数据块中。

PCTUSED的作用是:当数据块中的数据量小于PCTUSED值时,此数据块将被记录于freelist中,允许其他数据再存放至此数据块中。

pctfree参数是控制freelist un-links的(即将块由freelists中移除)。设置pctfree=10 意味着每个块都保留10%的空间用作行扩展。

pctused参数是控制freelist re-links的。设置pctused=40意味着只有在块的使用低于40%时才会回到表格的freelists中。

PCTFREE和PCTUSED举例如下:

假设当前此两属性分别设置为PCTFREE=10,PCTUSED=80,则表示:
1、当数据块中的剩余容量小于10%时,此数据块不再记录于freelist中,不能再被插入数据,实际意义在于避免update操作将此块中的行使得行占用空间变大而导致行链接或者行迁移。
2、当此数据块的剩余容量大于20%时,此数据块被记录至freelist中,允许其他数据被插入。
PCTFREE和PCTUSED的值可以在创建表时指定,也可以在创建表后用修改,但是要注意的是,修改后的值,只对修改后的数据操作有影响,对之前的无效。
因为OLTP系统对数据块的DML操作会较为频繁,所以在OLTP系统中正确配置这两个属性可能会对性能有一定的提高。
在Oracle11g中,表空间默认使用本地位图自动管理,PCTFREE的默认值是10,且无法自定义管理PCTUSED属性,除非将表空间设置为手动管理。

实验一: 同一个表使用不同的PCTFREE和PCTUSED的值,所用BLOCK不同。

SQL> create tablespace users2 datafile 'f:\userdata\users2.dbf' size 10m autoextend on next 1m segment space management manual;
Tablespace created
SQL> drop tablespace users2 including contents and datafiles;
Tablespace dropped
SQL> create tablespace users2 datafile 'f:\userdata\users2.dbf' size 10m autoextend on next 1m segment space management manual;
Tablespace created
SQL> select * from tab;
TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
SYS_TEMP_FBT                   TABLE  
SQL>  create table test1 as select * from dba_objects;

Table created

需要手动执行命令进行表分析,来统计信息。如果不做的话,可能查不到表所占用的BLOCK信息。

如果不手动进行分析,系统会在 执行SQL的时候,自动采集样本统计信息,生成执行计划,此时为自动采集(SELECT也会采集)。这种自动采集过程,只收集一部分的样本数据用于统计信息,而手工收集是收集全部数据用于统计信息 ,因此后者计算的值更精确

blocks的信息必须是收集完整的统计信息才能给出 精确的值
动态采集 只是收集一部分数据样本信息,目的:用这部分样本 模拟出 整个表的执行计划,这是一个相似值,因此不可以作为精确值使用
如果要想看,必须执行全表统计分析
常用命令
execute dbms_stats.gather_table_stats(ownname=>'LEO1',tabname=>'LEO1',
method_opt=>'for all indexed columns size 254');
ownname=>'LEO1'   表用户名
tabname=>'LEO1'    统计分析表名
对leo1进行全表整体分析包括数据分布情况分析(数据倾斜程度,即直方图)

SQL> analyze table test1 compute statistics;

Table analyzed

进行查询,此时  pct_free值是10. pct_used未设置。占用的BLOCK是1051个。

SQL>  select pct_free,pct_used,blocks,avg_row_len,chain_cnt from tabs where table_name='TEST1';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10                  1051         100          0
SQL> alter table test1 pctfree 30;
Table altered
SQL> alter table test1 pctused 40;
Table altered
SQL> alter table test1 move tablespace users2;
Table altered
SQL> analyze table test1 compute statistics;

Table analyzed

进行查询,此时  pct_free值是40. pct_used  40。占用的BLOCK是1320个。因为块的剩余小于40时不能再插入数据。故比“块剩余小于10%不能再插入数据多占用的近1/3的块

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST1';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        30         40       1320         100          0
SQL>

实验二: 两个相同的表PCTUSED属性不同,删除同样一批数据后两个表所占用block的数量不同

结论是PCTUSED为 80的test3占用的block的数量明显比PCTUSED为40的test2占用的数量多。这是因为,删除同样的一大批数据后,Oracle会根据所操作块的PCTUSED属性判定此块是否可以被再次使用。test2的PCTUSED为40表示当块中的可用容量达到60%时,此块被标记为可用  ,而test3的PCTUSED为 80表示当块中的可用容量只要达到20%时,即可被标记为可用。这样如删除相同的数据,就会遇到test2
中的部分BLOCK可用容量低于60%,被标记为不可用,仍在占用着BLOCK。而test3中的BLOCK可用容量只要不低于20%,就会被插入数据,可以极大减少BLOCK使用量。
实验如下:

SQL> create table test2 tablespace users2 as select * from test1 where 1=2;
Table created
SQL> create table test3 tablespace users2 as select * from test1 where 1=2;
Table created
SQL> select count(*) from test3;
  COUNT(*)
----------
         0
SQL> select count(*) from test2;
  COUNT(*)
----------
         0
SQL> alter table test2 pctfree 15;
Table altered
SQL> alter table test2 pctused 40;
Table altered
SQL> alter table test3 pctfree 15;
Table altered
SQL> alter table test3 pctused 80;
Table altered
SQL> insert into test2 select * from test1;
71976 rows inserted
SQL> insert into test3 select * from test1;
71976 rows inserted
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST2';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        15         40                        
SQL> analyze table test2 compute statistics;
Table analyzed
SQL> analyze table test3 compute statistics;

Table analyzed

此时两个表TEST2 TEST3所占用的BLOCK大小相等

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST2';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        15         40       1083         100          0
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST3';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        15         80       1083         100          0
说明首次插入数入数据时分配的block数量,不受PCT_FREE   PCT_USED 影响。
删除同样多的数据:
SQL> delete from test2 where owner='SYS';
30870 rows deleted
SQL> delete from test3 where owner='SYS';
30870 rows deleted
SQL> insert into test3 select * from test1;
71976 rows inserted
SQL> insert into test2 select * from test1;
71976 rows inserted
SQL> analyze table test3 compute statistics;
Table analyzed
SQL> analyze table test2 compute statistics;
Table analyzed
 此时可以观察到:PCTUSED为 80的test3占用的block的数量明显比PCTUSED为40的test2占用的数量少。
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST3';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        15         80      
1723
         101          0
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'TEST2';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        15         40       2029         101          0

抱歉!评论已关闭.