インデックスの圧縮
Oracle Databaseの標準インデックスフォーマットであるB-Treeインデックスにはッセグメントを圧縮する機能が提供されています。ここでは圧縮指定により、セグメント・サイズがどの程度削減されるかを検証します。
Oracle Database 12cのインデックス圧縮指定はCREATE INDEX文に以下の指定を行います。
CREATE INDEX文指定 | 説明 | 備考 |
---|---|---|
COMPRESS n | 接頭辞圧縮を行う n には列数を指定 | |
COMPRESS ADVANCED LOW | 高速なアクセスを維持しながら圧縮を行う | COMPATIBLE 12.1.0以上 |
COMPRESS ADVANCED HIGH | アクセス性能よりも圧縮率を優先する | COMPATIBLE 12.2.0以上 |
Oracle Database 12c Release 2ではCOMPRESS ADVANCED HIGH句を指定できるようになりました。
検証方法
検証にはTPC-DSベンチマークのCUSTOMERテーブルを使いました。レコード数は100,000件です。
テーブル構造は以下の通りです。インデックスには一意な値が異なるC_CUSTOMER_SK列、C_CUSTOMER_ID列、C_FIRST_NAME列、
C_LAST_NAME列、C_BIRTH_YEAR列等を使いました。
列名 | データ型 | DISTINCT値 |
---|---|---|
C_CUSTOMER_SK | NUMBER(38) | 100,000 |
C_CUSTOMER_ID | CHAR(16) | 100,000 |
C_CURRENT_CDEMO_SK | NUMBER(38) | |
C_CURRENT_HDEMO_SK | NUMBER(38) | |
C_CURRENT_ADDR_SK | NUMBER(38) | |
C_FIRST_SHIPTO_DATE_SK | NUMBER(38) | |
C_FIRST_SALES_DATE_SK | NUMBER(38) | |
C_SALUTATION | CHAR(10) | |
C_FIRST_NAME | CHAR(20) | 4,131 |
C_LAST_NAME | CHAR(30) | 4,972 |
C_PREFERRED_CUST_FLAG | CHAR(1) | |
C_BIRTH_DAY | NUMBER(38) | |
C_BIRTH_MONTH | NUMBER(38) | 69 |
C_BIRTH_YEAR | NUMBER(38) | |
C_BIRTH_COUNTRY | VARCHAR2(20) | |
C_LOGIN | CHAR(13) | |
C_EMAIL_ADDRESS | CHAR(50) | |
C_LAST_REVIEW_DATE | CHAR(10) |
検証には以下のSQL文を使いました。
SQL> CREATE INDEX インデックス名 ON CUSTOMER (列指定) 圧縮指定;
SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS('TPCDS', 'インデックス名');
SQL> SELECT blocks FROM user_segments WHERE segment_name='インデックス名';
検証結果
B*Treeインデックスの圧縮効果は以下の通りです。
C_CUSTOMER_SK列
NUMBER型で、一意のデータが格納された列です。一意データなので接頭辞圧縮を指定するとかえってブロック数が増加しています。
一方でCOMPRESS ADVANCED HIGHを指定すると大幅にブロック・サイズが削減できています。
圧縮指定 | ブロック数 |
---|---|
圧縮無 | 128 |
COMPRESS | 192 |
COMPRESS ADVANCED LOW | 128 |
COMPRESS ADVANCED HIGH | 56 |
C_LAST_NAME列
CHAR(30)型で、データの種類は比較的多いのですが、同じデータもある列です。圧縮効果はありますが、どの圧縮方法でも同じデータ量になっています。
圧縮指定 | ブロック数 |
---|---|
圧縮無 | 320 |
COMPRESS | 128 |
COMPRESS ADVANCED LOW | 128 |
COMPRESS ADVANCED HIGH | 128 |
C_BIRTH_YEAR列
NUMBER型でデータ種類が少なく、インデックスが効きにくい列です。COMPRESS ADVANCED HIGH指定以外では圧縮効果がない結果になっています。
圧縮指定 | ブロック数 |
---|---|
圧縮無 | 128 |
COMPRESS | 128 |
COMPRESS ADVANCED LOW | 128 |
COMPRESS ADVANCED HIGH | 44 |
C_FIRST_NAME列とC_LAST_NAME列の組み合わせ
文字列型の複合インデックスの圧縮例です。通常の圧縮でも効果がありますが、COMPRESS ADVANCED HIGHを指定すると大幅に縮小できています。
圧縮指定 | ブロック数 |
---|---|
圧縮無 | 448 |
COMPRESS 1 | 320 |
COMPRESS 2 | 448 |
COMPRESS ADVANCED LOW | 320 |
COMPRESS ADVANCED HIGH | 128 |
C_CUSTOMER_SK列とC_CUSTOMER_ID列の組み合わせ
NUMBER型で一意なデータの複合インデックスの圧縮例です。通常の圧縮では効果が無く、COMPRESS ADVANCED HIGHを指定する縮小できています。
圧縮指定 | ブロック数 |
---|---|
圧縮無 | 256 |
COMPRESS 1 | 320 |
COMPRESS 2 | 320 |
COMPRESS ADVANCED LOW | 256 |
COMPRESS ADVANCED HIGH | 128 |
上記の結果から、Oracle Database 12c Release 2の新機能であるCOMPRESS ADVANCED HIGH指定は多くの場合、圧縮効果が高いことがわかります。
一方で、マニュアルによるとこの指定はインデックスへのアクセスは低速になると記述があるため、あまり参照されない過去データ等で利用が推奨されるのではないかと思われます。