Oracle 10g資料表壓縮的一些細節(上)
在Oracle 11g中,Advanced Compression是一個重要引入的新特性。Advanced Compression針對OLTP下的資料物件、Dataguard Redo Log等進行了較大程度的最佳化。在筆者之前的文章中,也針對此項特性進行了淺析。
目前,還有很多系統是執行在Oracle 10g乃至9i下,對這些系統而言,Oracle壓縮有一些什麼特性呢?本篇一起來探討。
1、環境準備
我們選擇Oracle 10gR2作為環境,同時準備原始資料表t_source,作為參照物件。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
準備資料,觀察在未使用10g壓縮特性情況下,資料空間使用情況。
SQL> create table t_source as select * from dba_objects where wner='SCOTT' or wner='SYSMAN';
Table created
SQL> select count(*) from t_source;
COUNT(*)
----------
1367
SQL> exec dbms_stats.gather_table_stats(user,'T_SOURCE',cascade => true);
PL/SQL procedure successfully completed
--段級別空間使用分析
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SOURCE';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 19 196608 24 3
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_SOURCE';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
1367 23 DISABLED
在利用所有行rowid情況,分析每個資料塊的平均容納行數。
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_source group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 20 46
4 21 76
4 22 76
4 23 74
4 24 78
4 4105 73
4 4106 71
4 4107 71
4 4108 73
4 4109 77
4 4110 76
4 4111 74
4 4112 73
4 4114 77
4 4115 74
4 4116 75
4 4117 45
4 4119 81
4 4120 77
19 rows selected
SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS from dba_extents where wner='SCOTT' and segment_name='T_SOURCE';
EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS
---------- ---------- ---------- ---------- ----------
0 4 17 65536 8 –第一個分割槽
1 4 4105 65536 8
2 4 4113 65536 8
從上面準備的資料表t_source的情況看,在沒有使用壓縮的情況下分配三個分割槽共24個資料塊。1367條記錄分佈在19個資料塊上,平均每個資料塊容納大約70-80行記錄。
2、壓縮表建立實驗
下面建立壓縮資料表。在建表的第一分割槽分配的時候,就採用壓縮方式進行。
SQL> create table t_compress compress as select * from t_source;
Table created
SQL> exec dbms_stats.gather_table_stats(user,'T_COMPRESS',cascade => true);
PL/SQL procedure successfully completed
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_COMPRESS';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 4123 131072 16 2
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_COMPRESS';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
1367 11 ENABLED
我們當建立資料表就指定compress選項,資料表建立後就是壓縮屬性的。相同的資料量,只分配了2個分割槽。下面看具體行的使用情況。
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_compress group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 4124 178
4 4125 199
4 4126 177
4 4127 197
4 4128 189
4 4129 185
4 4130 207
4 4131 35
8 rows selected
具體行在塊的分配上,只用到了8個資料塊進行儲存。平均每個資料塊容納資料行接近200行。
說明:當我們在建立資料表的時候,就指定了compress選項。那麼直接進行CATS插入的時候,壓縮功能開啟。同時,壓縮效果較優。
注意:我們這裡面使用的是CATS方式插入資料,而不是日常OLTP方式。兩種方式差異顯著。
3、變化分配資料插入實驗
CATS方式是一種“壓實”的插入方式。如果我們在變化過程中改變了資料表的壓縮選項,空間分配情況會如何呢?
我們首先準備一個資料表,非壓縮狀態下插入過一部分的資料。
--插入一部分資料;
SQL> create table t_sample as select * from t_source where mod(object_id,2)=0;
Table created
SQL> select count(*) from t_sample;
COUNT(*)
----------
695
SQL> exec dbms_stats.gather_table_stats(user,'T_SAMPLE',cascade => true);
PL/SQL procedure successfully completed
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SAMPLE';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 4139 131072 16 2
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_SAMPLE';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
695 13 DISABLED
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_sample group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 4140 80
4 4141 75
4 4142 74
4 4143 71
4 4144 74
4 4145 74
4 4146 75
4 4147 74
4 4148 79
4 4149 19
10 rows selected
分配情況和t_source的趨勢相似。我們修改資料表屬性。
SQL> alter table t_sample compress;
Table altered
SQL> exec dbms_stats.gather_table_stats(user,'T_SAMPLE',cascade => true);
PL/SQL procedure successfully completed
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SAMPLE';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 4139 131072 16 2
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_SAMPLE';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
695 13 ENABLED
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_sample group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 4140 80
4 4141 75
4 4142 74
4 4143 71
4 4144 74
4 4145 74
4 4146 75
4 4147 74
4 4148 79
4 4149 19
10 rows selected
注意:此時我們修改了資料表屬性,變化為compress。但是,現有資料並沒有被壓縮,而是保留為原有的情況。平均塊容量為80左右個資料行,而非壓縮下的上百行。
筆者此時猜想了一種可能,有沒有在內部已經進行了空間重排,形成行連結模式。經過測試,發現沒有行連結。而且在修改資料表compress屬性的時候,執行時間也沒有進行復雜變化的機會。
那麼,我們接下來插入剩下的資料,使用OLTP方式。
SQL> insert into t_sample select * from t_source where mod(object_id,2)=1;
672 rows inserted
SQL> commit;
Commit complete
SQL> select count(*) from t_sample;
COUNT(*)
----------
1367
SQL> exec dbms_stats.gather_table_stats(user,'T_SAMPLE',cascade => true);
PL/SQL procedure successfully completed
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SAMPLE';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 4139 196608 24 3
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_SAMPLE';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
1367 23 ENABLED
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_sample group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 4140 80
4 4141 75
4 4142 74
4 4143 71
4 4144 74
4 4145 74
4 4146 75
4 4147 74
4 4148 79
4 4149 19
4 4150 74
4 4151 78
4 4152 75
4 4162 74
4 4163 75
4 4164 77
4 4165 69
4 4167 72
4 4168 78
19 rows selected
注意:此時雖然是壓縮模式,但是使用OLTP insert方式後,資料表空間並沒有節省!新分配空間,依然是使用非壓縮方式——這點可以從塊行容量上看出來。
解決方法——Move操作
解決的方法,我們可以採用move移動。Move是一種對資料表物理儲存進行重排的過程,相當於在另一個磁碟上進行資料表重新組織,對應的空間乃至段頭都要發生變化。Move是我們經常使用的降低HWM的方法。
SQL> alter table t_sample move;
Table altered
SQL> exec dbms_stats.gather_table_stats(user,'T_SAMPLE',cascade => true);
PL/SQL procedure successfully completed
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SCOTT' and segment_name='T_SAMPLE';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
4 4171 131072 16 2
SQL> select NUM_ROWS, BLOCKS, Compression from dba_tables where wner='SCOTT' and table_name='T_SAMPLE';
NUM_ROWS BLOCKS COMPRESSION
---------- ---------- -----------
1367 11 ENABLED
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno, dbms_rowid.rowid_block_number(rowid) bno, count(*) from t_sample group by dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) order by bno;
FNO BNO COUNT(*)
---------- ---------- ----------
4 4172 173
4 4173 173
4 4174 170
4 4175 179
4 4176 173
4 4177 166
4 4178 182
4 4179 151
8 rows selected
結論,我們發現空間被壓縮,塊行容量增加。
上面的實驗,告訴我們幾個結論:
ü Compress是資料段的一個屬性。當我們單純進行compress和nocompress切換的時候,資料已經分配空間是不會發生變化的;
ü 即使在compress的資料表,當我們進行常規OLTP資料插入的時候,是不會應用壓縮選項的;
ü Move操作透過重新促使系統進行資料空間分配的配比,可以應用實現compress的結果——注意是結果,資料表被壓縮!
下面我們透過幾個極端情況實驗,繼續分析10gR2的Compression。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-719482/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 的表壓縮Oracle
- oracle壓縮表(二)Oracle
- oracle壓縮表(一)Oracle
- 壓縮錶轉非壓縮表(線上重定義)
- 【SHRINK】Oracle收縮表的詳細命令參考Oracle
- Oracle 10g 增刪節點Oracle 10g
- MySQL 5.6的表壓縮MySql
- Oracle案例11——Oracle表空間資料庫檔案收縮Oracle資料庫
- 在 Spark 資料匯入中的一些實踐細節Spark
- oracle 10g建立資料庫鏈的簡化Oracle 10g資料庫
- 壓縮資料以節省空間和提高速度(轉)
- Windows的壓縮資料夾(zip/cab)Windows
- 0910 – iPaste 搞定資料壓縮AST
- linux 下壓縮與解壓資料夾Linux
- 浪潮線上壓縮,為資料儲存降本增效
- c# 上傳壓縮包 解壓,遍歷資料夾和檔案C#
- Oracle 資料庫 10g中的分割槽功能(轉)Oracle資料庫
- Oracle 10g RAC 資料儲存更換Oracle 10g
- for 迴圈的一些細節
- Termux使用的一些細節UX
- Sqlserver表和索引壓縮SQLServer索引
- MYSQL壓縮表測試MySql
- 高效的資料壓縮編碼方式 Protobuf
- Java實現壓縮資料夾Java
- Hadoop(十九)MapReduce OutputFormat 資料壓縮HadoopORM
- 初學Golang的一些細節Golang
- AWS Graviton2上資料壓縮演算法效能比較演算法
- Linux下解壓命令、壓縮命令大全,詳細教程Linux
- 解析ws訂閱返回的GZIP 壓縮資料
- 關於資料庫壓縮技術的Survey資料庫
- 怎麼把資料夾壓縮成壓縮包發給微信好友
- Redis 的基礎資料結構(二) 整數集合、跳躍表、壓縮列表Redis資料結構
- kotlin對ZipInputStream與ZipOutputStream的一些擴充工具(壓縮,解壓)Kotlin
- openGauss 支援OLTP場景資料壓縮
- Linux加密壓縮檔案/資料夾Linux加密
- 序列化資料傳輸壓縮
- Oracle 10g大檔案表空間(轉)Oracle 10g
- Nginx網路壓縮 CSS壓縮 圖片壓縮 JSON壓縮NginxCSSJSON
- Canvas 縮放圖片中細節消失Canvas