設計一個例子,演示PCTUSED和PCTFREE對數據操作的影響

PCTUSEDPCTFREE是數據塊的存儲屬性,單位都是%

PCTFREE:表示什麼時候不可以再往塊中插入數據,但是更新數據和刪除數據是可以的。例如 我們設置爲20%,當數據塊空閒空間剩餘20%時候,這個數據塊就從空閒列表(free list)中移出,移出後我們就不能再往數據塊裏面插入數據了。對於數據塊中已有數據的更新可以使用數據塊中的保留空間,只有當數據塊的佔用空間比例(PCTUSED)低於40%時才能向其插入新數據。

PCTUSED:表示什麼時候可以繼續往塊中插入數據,例如 我們設置40%,只有當數據塊佔用容量低於40%時才允許再次插入新數據,此時數據塊會插入空閒列表(free list),數據塊就能夠繼續接受新記錄,過程如此往復循環。

PCTUSEDPCTFREE二者沒有任何關係,各做各的

場景:應用在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個數據塊,freelistfreelistgroupASSM表空間中根本不存在,僅在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_usedASSM模型下依然不會生效的,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:由你設置freelistsfreelistgroupspctusedpctfreeinitrans等參數來控制如何分配、使用段中的空間

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

我們修改一下pctfreepctused,可以看到在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資源開銷較大,在平時使用時可以根據業務特性結合測試結果靈活設定。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章