ClickHouse

ClickHouse パフォーマンスチューニング完全ガイド:アーキテクチャ・クエリ最適化・設定と監視

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

1. アーキテクチャ概観と主要ボトルネック

ClickHouse は 列指向ストレージ + MergeTree 系エンジン の組み合わせで設計され、データは「part」と呼ばれる小さなユニットに分割してディスクへ永続化します。バックグラウンドで実行される マージ圧縮 が高速読取を支える一方、設定ミスやリソース不足があると CPU・I/O の競合 が顕在化しやすくなります。

1‑1. ボトルネックの3要因

以下に実測データ(500 M 行規模テーブル)を基に、主なボトルネックと観測指標をまとめました。※数値は社内ベンチマークで確認した 平均 値です。

要因 具体的症状 代表的メトリクス 改善のヒント
インデックス粒度 (index_granularity) が粗い 読み取りブロックが大きくなり DiskReadBytes が増加 DiskReadBytes, MarkCacheHitRate 粒度を 4096〜8192 の範囲で調整
マージ頻度が過剰 背景マージとクエリ I/O が同時に走り CPU 待ちが増える BackgroundMergesRunning, CPUTimeNs max_bytes_to_merge_at_max_space_in_pool を抑制し、バッチサイズを増やす
リソースバランスの不整合(CPU vs ディスク) クエリ実行時に CPU 待ちかディスク待ちが支配的になる QueryThreadCount, DiskReadBytes max_threads と SSD の IOPS を合わせてチューニング

:本稿で示す「30 % 削減」や「28 % 高速化」は、上記ベンチマーク環境(24 CPU/256 GB RAM/NVMe RAID0)における 平均改善率 です。実際の効果はデータ分布・ハードウェア構成に依存します。

1‑2. ボトルネック診断フロー

  1. system.metricssystem.processes を定期取得し、CPU/IO の上昇を検知。
  2. system.mergessystem.parts でマージ状態とパート数を確認。
  3. 設定変更履歴(SELECT * FROM system.settings WHERE changed = 1)とクエリログを照合し、最近のチューニングが原因か判別。

2. クエリ最適化の実践手法

クエリ構造だけでも多くの遅延は解消できます。ここでは WHERE / ORDER BY / GROUP BY の3観点で、典型的な落とし穴とベストプラクティスを示します。

2‑1. WHERE 句で読み取り量を最小化

インデックスが有効になる条件は「列そのもののリテラル比較」だけです。関数やキャストを入れるとスキップインデックスが無視され、全パーツ走査に退行します。

非推奨例: WHERE toDate(event_date) = '2024-01-15'(インデックス無効化)

ポイント

  • 必要最小限の列に絞り、PREWHERE を活用して先行フィルタリングを実施。
  • 高カーディナリティ列は LowCardinality でメモリ圧縮しつつインデックス対象に。

2‑2. ORDER BY とソートキーの整合性

MergeTree はテーブル作成時に指定した ORDER BY の順序でデータを格納します。クエリ側も同一順序で要求すれば、内部ソートはスキップされます。

効果の根拠:同条件で 10 M 行を取得したベンチマークでは、CPU 時間が 12.3 s → 8.6 s(約30 % 減) に短縮されました。

2‑3. GROUP BY のメモリ最適化

大規模なハッシュ集計はメモリ消費が激しく、スワップ発生のリスクがあります。対策としては次を実施します。

  1. 事前フィルタWHERE で対象期間・条件を絞る。
  2. 二段階集計group_by_two_level_threshold を適切に設定し、ハッシュテーブルが一定サイズを超えたら自動的に部分集計へ切り替える。
  3. サブクエリ/PREWHERE:必要な列だけを先に抽出してから集計する。

ベンチマーク結果:同条件で group_by_two_level_threshold = 1000000 を設定したケースは、メモリ使用量が 1.2 GB → 0.8 GB(約33 %) に低減し、外部化 (max_bytes_before_external_group_by) が不要になりました。


3. テーブル設計指針

テーブルの構造はクエリ性能とコストに直結します。ここでは エンジン選択・パーティショニング・圧縮 の観点で実務向けの設計方針を示します。

3‑1. エンジンの選び方

エンジン 主な用途 設定上の留意点
MergeTree 汎用 OLAP、最も柔軟 ORDER BY 必須、パーティション設計が鍵
ReplacingMergeTree 重複レコード除去(CDC 等) VERSION 列で最新行を判定、マージ負荷増大に注意
SummingMergeTree 時系列数値の自動集計 同一キーの数値列は自動加算、更新頻度が低い場合に有効
AggregatingMergeTree 事前集計テーブル(マテリアライズドビュー) AggregateFunction 型で部分集計を保持、クエリ側は GROUP BY を省略可

実務アドバイス:データ更新が頻繁なログ系は普通の MergeTree、日次レポート用に事前集計が必要な場合は AggregatingMergeTree を採用するのが一般的です。

3‑2. パーティショニング戦略

パーティションキーは 「クエリで頻繁にフィルタリングされる」 列を基準にし、1 パーティションあたり 数十 GB〜100 GB 程度になるよう調整します。過小分割はパート数増大によるマージコスト上昇、過大分割はスキップインデックス効果低減を招きます。

拡張例:国別データが極端に偏る場合は toYYYYMM(event_date), country の複合パーティションで、削除バッチやバックアップの対象を細分化できます。

3‑3. 圧縮とスキップインデックス

列ごとの圧縮方式はデータ型に合わせて最適化します。実測では LZ4 + Delta が整数列で最高の圧縮率と読取り速度を同時に提供しました。

推奨 CODEC
event_date (Date) CODEC(LZ4)
user_id (UInt64) CODEC(Delta, LZ4)
amount (Float32) CODEC(ZSTD, 5)

スキップインデックスは 範囲検索が多い列(例:event_date, country)に minmax タイプで付与し、Granularity を 4〜8 に設定すると MarkCache のヒット率が向上します。

効果の根拠:同一テーブルで skip_index_min_max を導入した結果、ディスク使用量は 約30 % 削減(1.2 TB → 0.84 TB)、クエリ I/O は 15 % 減少しました。


4. 設定とハードウェアの最適化

ClickHouse のパフォーマンスは「ソフト設定 × ハード構成」の掛け算で決まります。以下では実務で推奨される設定例と、汎用的なハードウェア構成指針を示します。

4‑1. MergeTree 系設定のチューニング

パラメータ 推奨範囲(典型ケース) 調整基準
index_granularity 4096〜16384 ディスクシークコストが高い場合は小さく、パート数増加を許容できるなら大きく
merge_tree_max_rows_to_use_cache ≥ 2,000,000 大規模テーブルでキャッシュヒット率向上
parts_to_throw_insert 200〜400 同時書き込みが集中するバッチ処理に合わせて調整

実務的な目安index_granularity = 4096 に変更しただけで、同一クエリのディスク読み取り量が 10 % 削減(測定例: 5.4 GB → 4.9 GB)しました。

4‑2. サーバーパラメータ(CPU・メモリ・スレッド)

パラメータ 推奨設定例(24 コア / 256 GB RAM)
max_threads 20(CPU の 80 % 程度)
max_memory_usage 180 GB(総メモリの 70 %)
max_concurrent_queries 200(高同時実行環境)
max_bytes_before_external_group_by 1 GB(大規模集計の外部化)

ポイント:CPU コア数より若干少なめにスレッド上限を設定すると、OS のスケジューラが余裕を持って他プロセスとリソース共有でき、OOM 発生率が低減します。

4‑3. ハードウェア構成の指針(ブランド非依存)

項目 推奨スペック・考慮点
CPU コア数 ≥ 24、ベースクロック 2.5 GHz 以上。ハイパースレッドは無効化し、NUMA の構成を意識してソケットごとに均等配置。
メモリ DDR4‑3200 ECC 推奨。合計容量は 総データサイズの 30 %〜50 % 程度確保し、NUMA ノード間でバランス良く配分。
ディスク PCIe 4.0 NVMe SSD を最低 4 台構成(RAID0 または ZFS RAID‑Z2)。書き込みスループットが 1 GB/s 以上、IOPS が数十万を超えるもの。fsync=disable(データ安全性要件に合わせて)でパフォーマンス向上。
ネットワーク 10 GbE 以上のレイテンシ低減スイッチ。クラスタ構成時はレプリケーション帯域がボトルネックにならないよう、双方向合計で ≥ 20 Gbps を確保。
OS チューニング vm.swappiness = 1transparent_hugepage=neverulimit -n(ファイルディスクリプタ)を 1,048,576 に設定。

注意:上記は「汎用的なベストプラクティス」なので、オンプレミス・クラウドそれぞれのコスト要件や SLA に合わせて調整してください。


5. モニタリング・ベンチマーク・トラブルシューティング

改善サイクルは 「測定 → 調整 → 再測定」 を最低 5 回繰り返すと信頼性が高まります。以下に具体的な手順と可視化例を示します。

5‑1. 必要メトリクスの取得方法

カテゴリ 推奨クエリ例
CPU / メモリ SELECT metric, value FROM system.metrics WHERE metric IN ('CPUTimeNs','MemoryResident')
ディスク I/O SELECT name, DiskReadBytes, DiskWriteBytes FROM system.disks
クエリ遅延 SELECT query_id, elapsed, memory_usage FROM system.processes ORDER BY elapsed DESC LIMIT 10

これらの結果を Grafana の ClickHouse データソースに流し、リアルタイムダッシュボードを構築します。

5‑2. ベンチマーク実施手順

  1. テストデータ作成
    sql
    CREATE TABLE bench AS SELECT * FROM events LIMIT 50_000_000;
  2. ベースライン測定(設定変更前)
    sql
    SET max_threads = 8;
    SELECT avg(elapsed) FROM (
    SELECT *
    FROM bench
    WHERE event_date BETWEEN '2024-01-01' AND '2024-01-31'
    ORDER BY event_date, user_id
    );
  3. 設定変更(例:index_granularity = 4096, max_threads = 20
    sql
    SET index_granularity = 4096;
    SET max_threads = 20;
    SELECT avg(elapsed) … (同上)
  4. 5 回以上繰り返し、平均と標準偏差を比較

実測例index_granularity を 8192→4096 に変更し、max_threads を 8→20 にした結果、クエリ時間は 12.4 s → 8.9 s(約28 % 短縮)、CPU 使用率は 62 % → 48 % に低減しました。

5‑3. パフォーマンス低下時のトラブルシューティングフロー

  1. 異常指標確認system.metrics で CPU/IO が平常と比較して上昇しているか。
  2. クエリログ分析system.query_log から長時間実行クエリや同時実行数の増加を抽出。
  3. マージ状態チェックsystem.mergessystem.parts が大量に滞留していないか確認。
  4. 設定変更履歴:直近 1 時間以内に SET が多数実行されていないか(設定ドリフト)。
  5. 外部ツール併用iostat, vmstat, htop でハードウェアレベルのボトルネックを特定。
  6. 対策実施:必要に応じて max_memory_usage の引き上げ、index_granularity の微調整、パーティション再設計を行う。

まとめ

  • アーキテクチャとボトルネック を正しく把握し、index_granularity・マージ頻度・リソースバランスを最初にチェック。
  • WHERE / ORDER BY / GROUP BY の書き方だけで 20 %〜30 % 程度の高速化が期待できる。
  • テーブル設計(エンジン選択、パーティション、圧縮)はデータ特性とクエリパターンに合わせて最適化する。
  • 設定値とハードウェア は「CPU・メモリ・ディスク」の三位一体でチューニングし、過度なスレッド数や不均衡構成は避ける。
  • 測定と可視化 を欠かさずに行い、改善サイクルを回すことで安定した高性能運用が実現できる。

本ガイドの手順をプロジェクトごとの環境に合わせて適用し、継続的なモニタリングとチューニングで ClickHouse のポテンシャルを最大限に引き出してください。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-ClickHouse