LinuxEye - Linux系统教程

LinuxEye - Linux系统教程

当前位置: 主页 > 数据库 >

Oracle数据块PCTUSED和PCTFREE属性对数据操作的影响

时间:2013-06-20 21:18来源:wubiaoblog.com/archives/753 编辑:吴飚 点击:
Oracle对数据块的管理有两个很重要的属性:PCTFREE和PCTUSED。PCTFREE的作用是:当数据块的剩余容量达到PCTFREE值时,此数据块不再被记录于freelist中,不允许其他数据再存放至数据块中。P
Oracle对数据块的管理有两个很重要的属性:PCTFREE和PCTUSED。PCTFREE的作用是:当数据块的剩余容量达到PCTFREE值时,此数据块不再被记录于freelist中,不允许其他数据再存放至数据块中。PCTUSED的作用是:当数据块中的数据量小于PCTUSED值时,此数据块将被记录于freelist中,允许其他数据再存放至此数据块中。

假设当前此两属性分别设置为PCTFREE=10,PCTUSED=80,则表示:
1、当数据块中的剩余容量小于10%时,此数据块不再记录于freelist中,不能再被插入数据,实际意义在于避免update操作将此块中的行使得行占用空间变大而导致行链接或者行迁移。
2、当此数据块的剩余容量大于20%时,此数据块被记录至freelist中,允许其他数据被插入。

PCTFREE和PCTUSED的值可以在创建表时指定,也可以在创建表后用修改,但是要注意的是,修改后的值,只对修改后的数据操作有影响,对之前的无效。

因为OLTP系统对数据块的DML操作会较为频繁,所以在OLTP系统中正确配置这两个属性可能会对性能有一定的提高。

在Oracle11g中,表空间默认使用本地位图自动管理,PCTFREE的默认值是10,且无法自定义管理PCTUSED属性,除非将表空间设置为手动管理。

我觉得这两属性挺有意思的,想小研究下又懒得dump数据块,dump数据库实在看得头疼,这事咱不能多干!

我尝试下用通俗易懂的例子理解下这两属性。

环境:
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> show user;
USER is "SYS"

先看下默认的PCTFREE和PCTUSED:
SQL> select PCT_FREE,PCT_USED from dba_tables where table_name = 'EMP';

  PCT_FREE   PCT_USED
---------- ----------
        10

上面的查询可以看出,PCTFREE 的默认值是10,而PCT_USED是空,这是由于EMP所属表空间的段管理是默认的本地位图自动管理。

先了解下PCTFREE的用途。

这里采取移动表空间的方法观察PCTFREE生效后的数据情况。

新建测试表空间:
SQL> show parameter create_file_dest

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_create_file_dest                  string      /oracle_/oradata/mydb/
SQL> create tablespace users02 datafile size 100m autoextend on next 10m;

Tablespace created.

在默认的自动管理的users表空间上创建测试表t5:
SQL> create table t5 tablespace users as select * from dba_objects;
Table created.

SQL> analyze table t5 compute statistics;
Table analyzed.

表t5当前的PCTFREE为10,PCTUSED为空,皆为默认值,占用的的blocks数量为1018:
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T5';

  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10                  1018         100          0

修改PCTFREE和PCTUSED的值:
SQL> alter table t5 pctfree 40;
Table altered.

SQL> alter table t5 pctused 50;
Table altered.

将表t5移动至新建的表空间users02上:
SQL> alter table t5 move tablespace users02;
Table altered.

SQL> analyze table t5 compute statistics;
Table analyzed.

查看t5的相关属性,可以看到修改的PCTFREE已生效,而PCTUSED未生效依然为空,但是可以观察到此时占用的blocks为1529:
SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T5';

  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        40                  1529         100          0
由以上测试可以看出,在自动段管理的表空间上,无法自定义PCTUSED的值,修改无效,而将PCTFREE的值从10改为40后,同样的数据占用的blocks数量明显大大增加,原因很简单:PCTFREE为10的时候,一个block的90%的空间可用来存放数据,而PCTFREE为40时,只有60%的空间可以用来存放数据,而总数据量不变,所以要分配更多的block来存放数据。

如何自定义PCTUSED属性?答案是将表空间设置为手动管理。

重建users02表空间并设置为手动管理,然后再重演一次前面的操作:
SQL> drop tablespace users02 including contents;
Tablespace dropped.

SQL> show parameter create_file_dest
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_create_file_dest                  string      /oracle_/oradata/mydb/
SQL> create tablespace users02 datafile size 100m autoextend on next 10m segment space management manual;
Tablespace created.

SQL> create table t5 tablespace users as select * from dba_objects;
Table created.

SQL> analyze table t5 compute statistics;
Table analyzed.

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T5';

  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10                  1018         100          0

SQL> alter table t5 pctfree 40;
Table altered.

SQL> alter table t5 pctused 50;
Table altered.

SQL> alter table t5 move tablespace users02;
Table altered.

SQL> analyze table t5 compute statistics;
Table analyzed.

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T5';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        40         50       1496         100          0

可以看到此时的PCTUSED已生效,但是对于首次插入数据来说,PCTUSED并不影响分配的blocks。

继续观察

在users02表空间上再创建两个测试表,表中数据与前面的t5一样,在插入数据之前对两个表设置一样的PCTFREE和不一样的PCTUSED:
SQL> create table t_pct1 tablespace users02 as select * from t5 where 1 > 2;
Table created.

SQL> create table t_pct2 tablespace users02 as select * from t5 where 1 > 2;
Table created.

SQL> alter table t_pct1 pctfree 10;
Table altered.

SQL> alter table t_pct1 pctused 40;
Table altered.

SQL> alter table t_pct2 pctfree 10;
Table altered.

SQL> alter table t_pct2 pctused 80;
Table altered.

SQL> insert into t_pct1 select * from t5;
69789 rows created.

SQL> insert into t_pct2 select * from t5;
69789 rows created.

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT,NUM_FREELIST_BLOCKS from tabs where table_name = 'T_PCT1';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT NUM_FREELIST_BLOCKS
---------- ---------- ---------- ----------- ---------- -------------------
        10         40

SQL> analyze table t_pct1 compute statistics;
Table analyzed.

SQL> analyze table t_pct2 compute statistics;
Table analyzed.

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T_PCT1';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10         40        990         100          0

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T_PCT2';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10         80        990         100          0
上面的测试再一次验证了,PCTUSED属性不会影响表第一次插入数据时分配的block数量。

下面展示一下PCTUSED影响分配block数量的情况

方案是,先在t_pct1、t_pct2中删除一批相同的数据,再插入一批相同的数据:
SQL> delete from t_pct1 where owner='SYS';
30550 rows deleted.

SQL> delete from t_pct2 where owner='SYS';
30550 rows deleted.

SQL> insert into t_pct1 select * from t5;
69789 rows created.

SQL> insert into t_pct2 select * from t5;
69789 rows created.

SQL> analyze table t_pct1 compute statistics;
Table analyzed.

SQL> analyze table t_pct2 compute statistics;
Table analyzed.

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T_PCT1';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10         40       1859         101          0

SQL> select PCT_FREE,PCT_USED,BLOCKS,AVG_ROW_LEN,CHAIN_CNT from tabs where table_name = 'T_PCT2';
  PCT_FREE   PCT_USED     BLOCKS AVG_ROW_LEN  CHAIN_CNT
---------- ---------- ---------- ----------- ----------
        10         80       1553         101          0
可以看到,最后t_pct2占用的block的数量明显比t_pct1占用的数量少很多,这是因为,删除同样的一大批数据后,Oracle会根据所操作块的PCTUSED属性判定此块是否可以被再次使用。t_pct1的PCTUSED为40表示当块中的可用容量达到60%时,此块被标记为可用,而t_pct2的PCTUSED为80表示当块中的可用容量只要达到20%时,即可被标记为可用,答案显而易见。

转载请保留固定链接: https://linuxeye.com/database/1779.html

------分隔线----------------------------
标签:PCTUSEDOraclePCTFREE
栏目列表
推荐内容