メインコンテンツまでスキップ
メインコンテンツまでスキップ

OPTIMIZE FINALの使用を避ける

ClickHouse テーブルは MergeTree エンジン を使用して、ディスク上に 不変のパーツ としてデータを保存します。これは、データが挿入されるたびに作成されます。

各挿入は、ソートされ圧縮されたカラムファイルを含む新しいパーツを作成し、インデックスやチェックサムなどのメタデータも含まれます。パーツ構造やそれらの形成方法についての詳細な説明には、この ガイド をお勧めします。

時間が経つにつれて、バックグラウンドプロセスが小さなパーツをより大きなものにマージして、断片化を減らし、クエリパフォーマンスを向上させます。

Simple merges

手動でこのマージをトリガーすることは魅力的ですが、以下のコマンドを使用することは避けるべきです:

OPTIMIZE TABLE <table> FINAL;

ほとんどの場合、OPTIMIZE FINAL 操作を避けるべきです。これは、資源集約的な操作を開始し、クラスターのパフォーマンスに影響を及ぼす可能性があります。

OPTIMIZE FINAL vs FINAL

OPTIMIZE FINALFINAL とは異なり、たとえば ReplacingMergeTree のように、重複なしで結果を得るために使用する必要がある場合があります。一般的に、クエリが主キーにある同じカラムでフィルター処理されている場合、FINAL の使用は問題ありません。

なぜ避けるべきか?

高コスト

OPTIMIZE FINAL を実行すると、ClickHouse は すべての アクティブなパーツを 単一のパーツ にマージすることを強制します。これには、大きなマージがすでに行われている場合でも含まれます。これには以下が含まれます:

  1. すべてのパーツをデコンプレッサします
  2. データをマージします
  3. 再び圧縮します
  4. 最終パーツをディスクまたはオブジェクトストレージに書き込みます

これらのステップは CPU および I/O 集約的 であり、特に大規模なデータセットを扱う場合にシステムに大きな負担をかける可能性があります。

安全制限を無視する

通常、ClickHouse は ~150 GB より大きなパーツのマージを回避します(max_bytes_to_merge_at_max_space_in_pool を介して設定可能)。しかし、OPTIMIZE FINALこの保護策を無視します。これにより、次のようなことが考えられます:

  • 複数の 150 GB のパーツを 1 つの巨大なパーツにマージしようとする可能性があります
  • これにより マージ時間が長くなったり、メモリ圧迫や メモリエラー が発生することがあります
  • これらの大きなパーツは、さらにマージするのが難しくなる可能性があります。すなわち、上記の理由でマージが失敗する場合があります。正しいクエリ時挙動のためにマージが必要な場合、これによって望ましくない結果が生じることがあります。例えば、ReplacingMergeTree において重複が蓄積される ことによって、クエリ時パフォーマンスが低下することがあります。

バックグラウンドマージに任せる

ClickHouse はすでにストレージとクエリの効率を最適化するために賢いバックグラウンドマージを実行しています。これらはインクリメンタルでリソースに配慮し、設定されたしきい値を尊重します。非常に特定のニーズがない限り(例:テーブルをフリーズする前にデータを確定する、またはエクスポートする)、ClickHouse にマージを自動的に管理させる方が良いです