この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
PostgreSQL 由来の Redshift には VACUUM コマンドがあります。
Redshift の VACUUM コマンドには、テーブルに指定されているソートキーに従ってソートが行われたり、削除対象としてマークされた行が解放され領域が確保されるといった効果があります。
通常、テーブルの行数をカウントする場合にはCOUNT 関数を用いますが、削除対象としてマークされた行も含めた行数を知りたい場合は「SVV_TABLE_INFO.TBL_ROWS」を参照します。
SELECT TBL_ROWS
FROM SVV_TABLE_INFO
WHERE "SCHEMA" = 'cm_inage_toru'
AND "TABLE" = 'sample_codes';
削除対象としてマークされている行・されていない行の比率は下記のようなクエリで得ることができます。
SELECT ROWS1,
ROWS2,
1 - ROWS1 / ROWS2 AS DELETE_MARK_RATE,
ROWS1 / ROWS2 AS NON_DELETE_MARK_RATE
FROM (SELECT COUNT(*) AS ROWS1 FROM cm_inage_toru.sample_codes),
(SELECT TBL_ROWS AS ROWS2
FROM SVV_TABLE_INFO
WHERE "SCHEMA" = 'cm_inage_toru'
AND "TABLE" = 'sample_codes');
削除しきい値
VACUUM コマンドにはしきい値が設定されており、デフォルトでは「95%」となっています。 この「95%」がどのように働くかというと、「削除対象としてマークされた行も含めた全体のうち少なくとも『5%(100% - 95%)』の行が削除対象としてマークされている場合に削除フェイズが実施される」といったものになります。
少し乱暴ですが「しきい値(threshold)が高いほど削除フェイズが実施されやすく低いほど実施されにくい」とも言えるかと思います。(100% では必ず実施され、0% では実施されません。)
- 実施されやすい
- 削除対象としてマークされた行の割合が小さくても削除フェイズが実施される。
- 実施されにくい
- 削除対象としてマークされた行の割合が大きくなければ削除フェイズが実施されない。
また、「少なくとも」と表現されている通り、しきい値を境に明確に全ての削除マーク付き行が解放される訳ではないようです。 以下は削除対象としてマークされている行が全体の 1% から 9% の時に「VACUUM DELETE ONLY(デフォルト 95%)」を実施した結果となります。
削除対象としてマークされている行 = 1%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 99 | 100 | 0.01 | 0.99
-------+-------+-------+------------------+---------------------
after | 99 | 100 | 0.01 | 0.99
削除対象としてマークされている行 = 2%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 98 | 100 | 0.02 | 0.98
-------+-------+-------+------------------+---------------------
after | 98 | 100 | 0.02 | 0.98
削除対象としてマークされている行 = 3%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 97 | 100 | 0.03 | 0.97
-------+-------+-------+------------------+---------------------
after | 97 | 100 | 0.03 | 0.97
削除対象としてマークされている行 = 4%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 96 | 100 | 0.04 | 0.96
-------+-------+-------+------------------+---------------------
after | 96 | 100 | 0.04 | 0.96
削除対象としてマークされている行 = 5%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 95 | 100 | 0.05 | 0.95
-------+-------+-------+------------------+---------------------
after | 95 | 98 | 0.03 | 0.97
5% から、全てではありませんが削除対象としてマークされた行が解放され始めました。
削除対象としてマークされている行 = 6%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 94 | 100 | 0.06 | 0.94
-------+-------+-------+------------------+---------------------
after | 94 | 96 | 0.02 | 0.98
削除対象としてマークされている行 = 7%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 93 | 100 | 0.07 | 0.93
-------+-------+-------+------------------+---------------------
after | 93 | 94 | 0.01 | 0.99
削除対象としてマークされている行 = 8%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 92 | 100 | 0.08 | 0.92
-------+-------+-------+------------------+---------------------
after | 92 | 92 | 0.00 | 1.00
削除対象としてマークされている行 = 9%
vacuum | rows1 | rows2 | delete_mark_rate | non_delete_mark_rate
-------+-------+-------+------------------+---------------------
before | 91 | 100 | 0.09 | 0.91
-------+-------+-------+------------------+---------------------
after | 91 | 91 | 0.00 | 1.00
まとめ
VACUUM は時間がかかることの多い処理であるため、可能であればスキップさせたいケースもあるかと思います。テーブルのサイズ増をどの程度まで許容できるかを検討しながら「しきい値(threshold)」を設定すれば、並列で発行できない VACUUUM コマンドの処理時間を最適化できるのではないかと思います。