If you are going to archive a table having a very large amount of data from a running system into a historical table and you expect from this archived table to be read-only then you have better to use the free BASIC compression mode instead of the paid OLTP mode. This article aims to show you the reason for this compression mode preference based on real life example.
In order to take advantage from the free BASIC compression mode you need first to insert data using a direct path load (this is why this compression mode used to be known as compression for direct path load operations or bulk load operations) and ensure that there is no trigger or integrity constraint on the inserted table that will make Oracle silently ignoring your requested direct path load mode. In passing, in contrast to the preceding Oracle releases, 12.1.0.2 Oracle database will inform you when a direct path is ignored via the Note at the bottom of the corresponding insert execution plan:
Note ----- - PDML disabled because triggers are defined - Direct Load disabled because triggers are defined
Here’s an example of BASIC compression I’ve executed on a 12.1.0.2 database?
SELECT t.owner, t.table_name, t.compress_for, s.bytes/1024/1024/1024 GB FROM dba_tables t , dba_segments s WHERE s.segment_name = t.table_name AND s.owner = 'XXX' AND t.table_name = 'T1' ORDER BY 4; OWNER TABLE_NAME COMPRESS_FOR GB ---------- ------------ ------------- ---------- XXX T1 263.114136
263 GB worth of data of which we need to keep only 2 years and archive the rest.
The first step in this process was to create an empty table cloned from the production table and define it to accept the BASIC mode compression:
-- create a table compressed with BASIC mode CREATE TABLE T1_HIST COMPRESS BASIC TABLESPACE HIST_TABSPACE AS SELECT * FROM T1 WHERE 1 = 2;
As far as I was going to send a huge amount of data into this archived table I decided to use a parallel insert which needs to be preceded by enabling parallel DML either by altering the session or by using the appropriate hint (for 12c)
-- enable parallel dml SQL> alter session enable parallel dml;
The way is now paved to start sending historical data into their new destination:
-- direct path load data older than 2 years into the archived table INSERT /*+ append parallel(bsic,4) */ INTO T1_HIST bsic SELECT /*+ parallel(oltp,4) */ * FROM T1 oltp WHERE HIST_DAT > add_months(sysdate,-24); 2,234,898,367 rows created.
More than 2 billion of rows direct path loaded.
And the agreeable surprise is:
SQL> SELECT t.owner, t.table_name, t.compress_for, s.bytes/1024/1024/1024 GB FROM dba_tables t , dba_segments s WHERE t.compress_for ='BASIC' AND s.segment_name = t.table_name AND s.owner = 'XXX' ORDER BY 4; OWNER TABLE_NAME COMPRESS_FOR GB ---------- ------------ ------------- ---------- XXX T1_HIST BASIC 53.2504272
We went from a source table with 263GB worth of data to a cloned table compressed using BASIC mode to end up with only 53GB or historical data.
If you are wondering how much rows I have not send into the archived table then here’s
SQL> select /*+ parallel(8) */ count(1) from T1 where HIST_DAT <= add_months(sysdate,-24); 7,571,098
This means that using the BASIC free compression mode I have archived almost all rows from the production table and succeeded to pack the initial 263GB into 53GB only. That’s an excellent compression ratio of 5 (we have divided the initial size by 5). Though that Oracle is saying that the compression ration depends on the nature of your data and it could range between a factor of 2x to 4x.
Should you have used the paid OLTP compression mode you would have got an archived table with a size approximatively 10% higher (~60GB). This is due to Oracle considering the table compressed in BASIC mode to be read only and not subject to any update with a default PCT_FREE set to 0 behind the scene:
SQL> select table_name, pct_free from dba_tables where table_name = 'T1_HIST'; TABLE_NAME PCT_FREE ----------- ---------- T1_HIST 0
As you can see, if you intend to archive a huge amount of data into a read only table, want to gain disk space with this operation and you don’t want to pay for the OLTP compression then you can opt for the free BASIC compression mode.
There are few interesting things that come up along with this archiving process. Particularly the new 12c way (HYBRID TSM/HWMB) Oracle is using to keep down the number of new extents and to avoid HV enqueue wait event during parallel direct path load with a high DOP across several instances:
SQL Plan Monitoring Details (Plan Hash Value=3423860299) ==================================================================================== | Id | Operation | Name | Rows |Execs | Rows | | | | | (Estim) | | (Actual) | ==================================================================================== | 0 | INSERT STATEMENT | | | 5 | 8 | | 1 | PX COORDINATOR | | | 5 | 8 | | 2 | PX SEND QC (RANDOM) | :TQ10000 | 819M | 4 | 8 | | 3 | LOAD AS SELECT (HYBRID TSM/HWMB) | | | 4 | 8 | | 4 | OPTIMIZER STATISTICS GATHERING | | 819M | 4 | 2G | | 5 | PX BLOCK ITERATOR | | 819M | 4 | 2G | | 6 | TABLE ACCESS FULL | T1 | 819M | 442 | 2G | ==================================================================================== Predicate Information (identified by operation id): --------------------------------------------------- 6 - access(:Z>=:Z AND :Z<=:Z) filter("HIST_DAT">ADD_MONTHS(SYSDATE@!,-24)) Note ----- - Degree of Parallelism is 4 because of table property
But this will be detailed in a separate blog article.