前回のRedshiftのストレージ容量のメンテナンスで取りあげたSVV_TABLE_INFOシステムビュー。
このビューにencodedというフィールドがあるのですが
所どころ「N」なってたりすることがあります。
rsdb1=# select * from SVV_TABLE_INFO;
database | schema | table_id | table | encoded | diststyle | sortkey1 | max_varchar | sortkey1_enc | sortkey_num | size | pct_used | empty | unsorted | stats_off | tbl_rows | skew_sortkey1 | skew_rows
----------+--------+----------+---------+---------+-----------+----------+-------------+--------------+-------------+------+----------+-------+----------+-----------+-----------+---------------+-----------
rsdb1 | public | 100523 | table2 | Y | EVEN | | 4096 | | 0 | 190 | 0.0498 | 0 | | 11.34 | 932239 | |
rsdb1 | public | 100617 | table3 | Y | EVEN | | 4096 | | 0 | 591 | 0.1549 | 0 | | 8.96 | 8566046 | |
rsdb1 | public | 100747 | table4 | N | EVEN | | 4096 | | 0 | 8049 | 0.0466 | 0 | | 0.00 | 130690 | |
rsdb1 | public | 150278 | table5 | Y | EVEN | | 65535 | | 0 | 178 | 2.1103 | 0 | | 17.82 | 132678814 | |
rsdb1 | public | 159527 | table6 | Y | EVEN | | 512 | | 0 | 692 | 0.1814 | 0 | | 4.10 | 62850 | |
rsdb1 | public | 100565 | table7 | N | EVEN | | 4096 | | 0 | 7527 | 1.9734 | 0 | | 5.15 | 12146431 | |
encodedが意味しているところは、
「該当のテーブルのすべてのフィールド/列が非圧縮です」
ということ。
Redshiftは列圧縮機能が搭載されており、列ごとに任意に列圧縮モードが指定できます。
実際にはどのような列圧縮かを調べるには
各列ごとの定義状況が確認できるpg_table_defシステムカタログを参照するとよいです。
rsdb1=# SELECT * FROM pg_table_def WHERE tablename = 'table4';
schemaname | tablename | column | type | encoding | distkey | sortkey | notnull
------------+-------------------------+---------------------------------+-------------------------+----------+---------+---------+---------
public | table4 | customerid | character varying(20) | none | f | 0 | f
public | table4 | label | character varying(100) | none | f | 0 | f
public | table4 | impressions | bigint | none | f | 0 | f
public | table4 | grpid | bigint | none | f | 0 | f
public | table4 | grpname | character varying(256) | none | f | 0 | f
public | table4 | status | character varying(256) | none | f | 0 | f
public | table4 | type1 | character varying(256) | none | f | 0 | f
encodingが列圧縮のモードです。
すべて「none」と散々な状態・・orz
列圧縮のモードは以下を参照してみて下さい。
AWS Documentation » Amazon Redshift » データベース開発者ガイド » テーブルの設計 » 列圧縮タイプの選択 » 圧縮エンコード
列圧縮のモードはCreateTable文で指定できます
例えば
create table testtable1
(
id int,
text varchar(256) encode LZO
);
と指定すれば良い感じです。
指定しなくてもRedshiftがよしなに列圧縮モードを設定してくれるようですが
聞いた話では、COPYコマンドで流し込みを行ったときに自動で列圧縮モード指定が行われるが
insert文で1行1行インサートして入れた際はraw (非圧縮) になってしまうそうです。
列圧縮と聞くと、展開するときにCPUパワー使うから使いたくないという方もいるかと思いますが
その筋に方々は圧縮展開のCPUコストよりストレージからの読み込みバイト数によるIOコストのほうが格段に大きいので
列圧縮は大量データの高速化には最適という話も聞きます。
OLTPであれば少量のデータの読み書きが大量に発生しますが、
DWHでは書き込みはLOADで行い、それらのデータはたまにしか使わず、使う時は読み込みが大量!!・・
という使い方ですのでストレージの料金的なコストのほうを優先にしてもいいと思います。
ということで、encodedがNな非圧縮列ばかりのテーブルを見つけたら
1.同一内容の別名テーブルを用意(圧縮方法はしていしなくてもよい)
2.insert into 同一内容の別名テーブル名 select * from 元テーブル名
でさくっと内容を移す
3.一応count(*)をとったりsum()などの集計関数で値をもとめ内容が同じかを確認
4.元テーブルを削除、alter文で別名テーブル名のテーブル名を変更
と行うだけで感覚的にはテーブル容量が半分から3割程度に削減できます。