ClickHouse のパーティション
ClickHouse では、INSERTのみでUPDATE/DELETEが行えませんが、パーティションを使いデータを分割しておけば、パーティション単位では削除が可能です。
昔はDate型のカラムを使い、月単位でのパーティションしかできませんでしたが、最近のバージョンで任意のカラムでパーティション分割が行えるようになりました。
パーティションの指定方法
パーティションが使えるのは、MergeTree系のエンジンのみになります。
次のように、パーティションとして使うカラムと、ソート順を指定します。
CREATE TABLE partitioned_by_date(
log_date Date,
log String
) ENGINE = MergeTree PARTITION BY log_date ORDER BY log_date;
PARTITION BY (a, b) のように指定すれば、複数カラムをキーとしたパーティションも可能です。
パーティションを細かくしすぎると、性能が落ちるので、削除したい単位を考えて指定すると良いと思います。
パーティションをまたがっては圧縮がされないので、細かいパーティションにすると圧縮率が下がってしまいます。また、多くのパーティションをスキャンすると参照性能にも影響が出る可能性があります。
こちらに、月単位のパーティションから日単位に切換えて、7.7GB から 15GB にデータ量が増えたという記事があります。
https://www.altinity.com/blog/2017/11/8/custom-partitioning-in-clickhouse-1154310
パーティション指定で便利な日付関数
以下の関数を使うと、月、週、日別の指定ができます。
- 月単位:toYYYYMM(date/datetime)
- 日単位:toYYYYMMDD(datetime) ※時刻から日付にしたい場合
- 週単位:toMonday(date/datetime)
実行すると以下のようになります。
SELECT toYYYYMM(now())
┌─toYYYYMM(now())─┐
│ 201803 │
└─────────────────┘
SELECT toYYYYMMDD(now())
┌─toYYYYMMDD(now())─┐
│ 20180314 │
└───────────────────┘
SELECT toMonday(now())
┌─toMonday(now())─┐
│ 2018-03-12 │
└─────────────────┘
パーティションの確認と削除
MergeTree エンジンでは、INSERTするごとに、1つのpartが作られます。
このpartをバックグラウンドでマージして数を減らすことで、性能を維持しています。
system.parts テーブルには、このpartsの一覧が入っていますので、partitionごとに集計することで、パーティションのレコード数やサイズを確認することができます。
SELECT partition, sum(rows) AS rows, sum(bytes) AS bytes
FROM system.parts
WHERE active AND table = 'partitioned_by_date'
GROUP BY partition;
┌─partition──────┬─rows─┬─bytes─┐
│ \'2018-03-01\' │ 1 │ 440 │
│ \'2018-02-01\' │ 2 │ 878 │
└────────────────┴──────┴───────┘
削除するには ALTER TABLE table DROP PARTITION parttion を実行します。
ALTER TABLE partitioned_by_date
DROP PARTITION '2018-02-01'
Ok.
SELECT partition, sum(rows) AS rows, sum(bytes) AS bytes
FROM system.parts
WHERE active AND table = 'partitioned_by_date'
GROUP BY partition;
┌─partition──────┬─rows─┬─bytes─┐
│ \'2018-03-01\' │ 1 │ 440 │
└────────────────┴──────┴───────┘