パフォーマンス最適化: コミュニティによるテスト済み戦略
このガイドは、コミュニティミートアップから得られた知見のコレクションの一部です。より現実的な解決策や洞察については、特定の問題でブラウズできます。 Materialized Viewsに関して問題がありますか?Materialized Viewsのコミュニティインサイトガイドをチェックしてください。 クエリが遅いと感じており、さらに例が必要な場合は、Query Optimizationガイドもご覧ください。
カーディナリティによるソート(低いから高い)
ClickHouseの主インデックスは、低カーディナリティのカラムが最初に配置されると最も効果的に機能し、大きなデータのチャンクを効率的にスキップできます。キーの後半に配置された高カーディナリティのカラムは、それらのチャンク内で細かいソートを提供します。ユニークな値が少ないカラム(ステータス、カテゴリ、国など)から始め、ユニークな値が多いカラム(user_id、timestamp、session_idなど)で終了します。
カーディナリティと主インデックスに関する詳細なドキュメントも参照してください:
時間の粒度が重要
ORDER BY句でタイムスタンプを使用する際は、カーディナリティと精度のトレードオフを考慮してください。マイクロ秒精度のタイムスタンプは非常に高いカーディナリティ(行ごとにほぼ一意の値)を生成し、ClickHouseのスパース主インデックスの効果を減少させます。丸められたタイムスタンプはカーディナリティを下げ、より良いインデックススキッピングを可能にしますが、時間ベースのクエリの精度が失われます。
平均ではなく個々のクエリに焦点を当てる
ClickHouseのパフォーマンスをデバッグする際は、平均クエリ時間や全体システムのメトリクスに依存しないでください。代わりに、特定のクエリが遅い理由を特定します。システムは良好な平均パフォーマンスを持っていても、個々のクエリはメモリの枯渇、フィルタリングの不良、または高カーディナリティの操作によって苦しむことがあります。
ClickHouseのCTOであるアレクセイによると: 「正しい方法は、この特定のクエリが5秒で処理された理由を自問することです...中央値や他のクエリが迅速に処理されたかどうかは気にしません。私が気にするのは私のクエリだけです」
クエリが遅い場合は、平均を見てはいけません。「なぜこの特定のクエリが遅かったのか?」と自問し、実際のリソース使用パターンを調べてください。
メモリと行スキャン
Sentryは、400万人以上の開発者から日々数十億のイベントを処理する開発者優先のエラー追跡プラットフォームです。彼らの重要な洞察: 「この特定の状況でメモリを駆動するのはグルーピングキーのカーディナリティです」 - 高カーディナリティの集約は、行スキャンではなくメモリ枯渇によってパフォーマンスを低下させます。
クエリが失敗した場合、それがメモリの問題(グループが多すぎる)なのか、スキャンの問題(行が多すぎる)なのかを判断します。
GROUP BY user_id, error_message, url_path
のようなクエリは、すべてのユニークな値の組み合わせごとに別のメモリ状態を生成します。ユーザー、エラーの種類、URLパスの負荷が高いと、同時にメモリに保持される必要がある何百万もの集約状態が生成される可能性があります。
極端なケースでは、Sentryは決定論的サンプリングを使用します。10%のサンプルはメモリ使用量を90%削減し、ほとんどの集約の精度を約5%維持します:
これにより、同じユーザーがすべてのクエリに表示され、時間帯を越えて一貫した結果が得られます。重要な洞察: cityHash64()
は、同じ入力に対して一貫したハッシュ値を生成するため、user_id = 12345
は常に同じ値にハッシュされ、ユーザーは10%のサンプルに常に含まれるか、決して含まれない - クエリ間でのちらつきはありません。
Sentryのビットマスク最適化
高カーディナリティのカラム(URLなど)で集約する場合、各ユニークな値はメモリ内に別の集約状態を作成し、メモリの枯渇につながります。Sentryの解決策: 実際のURL文字列でグルーピングするのではなく、ビットマスクに収束するブール式でグルーピングします。
次のクエリは、この状況が該当する場合にあなたのテーブルで試すことができます:
ユニークな文字列をメモリに保存する代わりに、その文字列に関する質問への回答を整数として保存します。集約状態は、データの多様性にかかわらず、限界があり、小さくなります。
Sentryのエンジニアリングチームから: 「これらの重いクエリは10倍以上速くなり、メモリ使用量は100倍低下しました(そして、より重要なことに、限界があります)。私たちの大規模な顧客は、リプレイを検索する際にエラーを見ることがなくなり、私たちは任意のサイズの顧客をサポートできるようになりました。」
動画のソース
- Lost in the Haystack - Optimizing High Cardinality Aggregations - Sentryのメモリ最適化に関するプロダクションの教訓
- ClickHouse Performance Analysis - デバッグ手法のアレクセイ・ミロビドフ
- ClickHouse Meetup: Query Optimization Techniques - コミュニティの最適化戦略
次を読む: