Exadata, ZFS oraz Pillar Axiom umożliwiają stosowanie wysoce skutecznej kompresji kolumnowej HCC (Hybric Columnar Compression) – ciekawy opis znajduje się tu. Funkcjonalność HCC jest jednak wbudowana w każde wydanie serwera bazy danych Oracle Database 12c (nie tylko Exadata), lecz możliwość jej użycia jest blokowana na zasadzie „nie, bo nie”. Pomysły na jej odblokowanie publikowali już Jonathan Lewis i Martin Berger. Natomiast zupełnie legalnie z HCC korzysta funkcja DBMS_COMPRESSION.GET_COMPRESSION_RATIO, która w celu oszacowania skuteczności kompresji fizycznie kompresuje naszą wybraną tabelę, a następnie dokonuje pomiarów osiągniętego stopnia kompresji (po czym tabelę usuwa…). Nie musimy posiadać Exadaty ani wskazanych przez Oracle systemów pamięci masowej aby korzystając z GET_COMPRESSION_RATIO skompresować „na próbę” tabelę i przekonać się, ile zyskalibyśmy dzięki takiej kompresji w środowisku produkcyjnym. Poniżej przykład testu stopnia kompresji HCC dla tabeli SH.SALES – uwaga na dwa bugi w implementacji GET_COMPRESSION_RATIO: (1) nie działa poprawnie przy wykonaniu równoległym (stąd w przykładzie PARALLEL_MAX_SERVERS=0) i (2) nie działa poprawnie przy polskich ustawieniach NLS (stąd NLS_LANGUAGE=american_america).
export NLS_LANG=american_america.us7ascii
sqlplus / as sysdba
ALTER SYSTEM SET PARALLEL_MAX_SERVERS=0 SCOPE=MEMORY;
SET SERVEROUTPUT ON
DECLARE
v_blkcnt_cmp PLS_INTEGER;
v_blkcnt_uncmp PLS_INTEGER;
v_row_cmp PLS_INTEGER;
v_row_uncmp PLS_INTEGER;
v_cmp_ratio NUMBER;
v_comptype_str VARCHAR2(32767);
BEGIN
DBMS_COMPRESSION.GET_COMPRESSION_RATIO(
scratchtbsname => 'USERS',
ownname => 'SH',
objname => 'SALES',
subobjname => NULL,
comptype => DBMS_COMPRESSION.COMP_ARCHIVE_HIGH,
blkcnt_cmp => v_blkcnt_cmp,
blkcnt_uncmp => v_blkcnt_uncmp,
row_cmp => v_row_cmp,
row_uncmp => v_row_uncmp,
cmp_ratio => v_cmp_ratio,
comptype_str => v_comptype_str,
subset_numrows => DBMS_COMPRESSION.COMP_RATIO_ALLROWS,
objtype => DBMS_COMPRESSION.OBJTYPE_TABLE
);
DBMS_OUTPUT.PUT_LINE('Stopien kompresji: ' || v_cmp_ratio);
DBMS_OUTPUT.PUT_LINE('Algorytm kompresji: ' || v_comptype_str);
END;
/
Stopien kompresji: 25
Algorytm kompresji: "Compress Archive High"
Jeżeli spodobała nam się 25-krotna kompresja, to wystarczy zatem wykonać (SH.SALES jest partycjonowana):
ALTER TABLE SH.SALES MOVE PARTITION ... COMPRESS FOR ARCHIVE HIGH;
…ale to już tylko na Exadata.