Abraham Lincoln said: “I can make more generals, but horses cost money”.
Often all I hear about Oracle Advanced Compression is: “.. but it is an extra option on top of Enterprise Edition”. And thus its hidden power is often neglected.
Advanced Compression is not just about having the data occupy less space on disk, tape or in the network. It is also about better performance of the database, deduplication and the utilization of less hardware resources: memory and CPU. Thus, you can consolidate more databases on the same server and reduce the license costs.
I will try to compress this blog post, I will make it as short as possible:
1. What and which tables to compress?
Compress the segments that are involved in most reads: physical, logical or unoptimized. Consider also the segments that are used in SQL statements having most reads.
But do not compress all of them! Use DBMS_COMPRESSION.GET_COMPRESSION_RATIO in order to verify that you will benefit from the compression. Do only those with “Compression Ratio” 2 to 1 and higher. Here is an example of how you can estimate the compression ratio:
set serveroutput on DECLARE blkcnt_cmp pls_integer; blkcnt_uncmp pls_integer; row_cmp pls_integer; row_uncmp pls_integer; cmp_ratio pls_integer; comptype_str varchar2(100); BEGIN DBMS_COMPRESSION.GET_COMPRESSION_RATIO ('PSAPSR3', 'SAPSR3', '/BI0/PMATERIAL', '',DBMS_COMPRESSION.COMP_FOR_OLTP, blkcnt_cmp, blkcnt_uncmp, row_cmp, row_uncmp, cmp_ratio, comptype_str); DBMS_OUTPUT.PUT_LINE('Block count compressed = ' || blkcnt_cmp); DBMS_OUTPUT.PUT_LINE('Block count uncompressed = ' || blkcnt_uncmp); DBMS_OUTPUT.PUT_LINE('Row count per block compressed = ' || row_cmp); DBMS_OUTPUT.PUT_LINE('Row count per block uncompressed = ' || row_uncmp); DBMS_OUTPUT.PUT_LINE('Compression type = ' || comptype_str); DBMS_OUTPUT.PUT_LINE('Compression ratio = '||round(blkcnt_uncmp/blkcnt_cmp,2)||' to 1'); DBMS_OUTPUT.PUT_LINE('Compression ratio org= '||cmp_ratio); END; /
2. How to measure the performance benefits of compression?
For the SQL statements run awrsqrpt.sql and compare the results:
Before Compression:
After Compression:
3. What comes after compression?
Follow the average CPU and I/O statistics for the compressed tables:
col c0 heading ‘Begin|Interval|time’ format a8 col c1 heading ‘Owner’ format a10 col c2 heading ‘Object|Type’ format a10 col c3 heading ‘Object|Name’ format a15 col c4 heading ‘Average|CPU|Cost’ format 9,999,999,999 col c5 heading ‘Average|IO|Cost’ format 9,999,999 select to_char(sn.begin_interval_time,'mm-dd hh24') c0, p.object_owner c1, p.object_type c2, p.object_name c3, avg(p.cpu_cost) c4, avg(p.io_cost) c5 from dba_hist_sql_plan p, dba_hist_sqlstat st, dba_hist_snapshot sn where p.object_name = '/BI0/PMATERIAL' and p.sql_id = st.sql_id and st.snap_id = sn.snap_id group by to_char(sn.begin_interval_time,'mm-dd hh24'), p.object_owner, p.object_type, p.object_name order by 1,2,3 desc;
P.S. About Exadata: do not mix HCC and DML, i.e., do not use HCC in OLTP.