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

クエリ実行の理解とアナライザー

ClickHouseはクエリを非常に迅速に処理しますが、クエリの実行は単純なプロセスではありません。SELECT クエリがどのように実行されるかを理解してみましょう。その説明にあたり、ClickHouseのテーブルにいくつかのデータを追加してみます。

ClickHouseにデータが追加されたので、いくつかのクエリを実行し、実行の理解を深めたいと思います。クエリの実行は多くのステップに分解されます。各クエリの実行ステップは、対応する EXPLAIN クエリを使用して分析およびトラブルシューティングできます。これらのステップは以下のチャートに要約されています:

クエリ実行時に各エンティティがどのように動作するかを見ていきましょう。いくつかのクエリを取り上げ、それらを EXPLAIN ステートメントを使って確認します。

パーサー

パーサーの目標は、クエリテキストをAST(抽象構文木)に変換することです。このステップは、EXPLAIN AST を使用して視覚化できます:

出力は、以下のように視覚化できる抽象構文木です:

各ノードには対応する子ノードがあり、全体の木構造はクエリの全体的な構造を表しています。これはクエリを処理するための論理構造です。エンドユーザーの視点から見ると(クエリ実行に興味がない限り)あまり役立ちません。このツールは主に開発者が使用します。

アナライザー

ClickHouseには現在アナライザーの2つのアーキテクチャがあります。enable_analyzer=0 を設定することで旧アーキテクチャを使用できます。新しいアーキテクチャはデフォルトで有効になっています。ここでは、旧アーキテクチャが新しいアナライザーが一般に利用可能になると廃止されることを考慮して、新しいアーキテクチャのみを説明します。

注記

新しいアーキテクチャはClickHouseのパフォーマンスを改善するためのより良いフレームワークを提供します。しかし、クエリ処理ステップの基本的な要素であるため、一部のクエリに負の影響を与える可能性もあり、既知の非互換性があります。クエリまたはユーザーレベルで enable_analyzer 設定を変更することで、旧アナライザーに戻ることができます。

アナライザーはクエリ実行の重要なステップです。ASTを受け取り、それをクエリツリーに変換します。ASTに対するクエリツリーの主な利点は、多くのコンポーネントが解決されていることです。たとえば、読み取るテーブルの情報やエイリアスも解決され、使用される異なるデータ型がツリーに知られています。これらの利点により、アナライザーは最適化を適用できます。これらの最適化は「パス」によって機能します。各パスは異なる最適化を探します。すべてのパスはこちらで確認できます。前述のクエリを実際に見てみましょう:

2つの実行間で、エイリアスとプロジェクションの解決を見ることができます。

プランナー

プランナーはクエリツリーを受け取り、そこからクエリプランを構築します。クエリツリーは特定のクエリを何をしたいかを教えてくれ、クエリプランはそれをどのように行うかを示します。クエリプランの一環として追加の最適化が行われます。クエリプランを見るには EXPLAIN PLAN または EXPLAIN を使用できます(EXPLAINEXPLAIN PLAN を実行します)。

この情報は提供されますが、さらに得たい情報があるかもしれません。例えば、プロジェクションが必要な列名を知りたい場合、クエリにヘッダーを追加できます:

これで、最後のプロジェクション(minimum_datemaximum_date、および percentage)のために作成する必要がある列名がわかります。しかし、実行する必要があるすべてのアクションの詳細も知りたいかもしれません。actions=1 を設定することで実現できます。

これで、使用されているすべての入力、関数、エイリアス、およびデータ型を確認できます。プランナーが適用する最適化の一部はこちらで見ることができます。

クエリパイプライン

クエリパイプラインはクエリプランから生成されます。クエリパイプラインはクエリプランと非常に似ていますが、木構造ではなくグラフです。ClickHouseがクエリをどのように実行し、どのリソースが使用されるかを明示します。クエリパイプラインを分析することは、入力/出力の観点でボトルネックを確認するために非常に役立ちます。前述のクエリを取り上げ、クエリパイプラインの実行を見てみましょう:

括弧内はクエリプランステップであり、その隣にプロセッサがあります。これは優れた情報ですが、これはグラフであるため、グラフとして視覚化すると良いでしょう。graph設定を1にして、出力フォーマットをTSVに指定することができます:

この出力をコピーして、こちらに貼り付けると、以下のグラフが生成されます:

白い長方形はパイプラインノードに対応し、灰色の長方形はクエリプランステップに対応し、xの後に続く数字は使用される入力/出力の数に対応します。コンパクトな形式で表示したくない場合は、compact=0を追加できます。

ClickHouseはなぜ複数のスレッドを使用してテーブルから読み取らないのでしょうか?テーブルにより多くのデータを追加してみましょう:

それでは、再度 EXPLAIN クエリを実行してみましょう:

このように、エグゼキュータはデータボリュームが十分に高くないため、操作を並列化しないことを決定しました。行を追加することで、エグゼキュータは複数のスレッドを使用することを決定しました、グラフに示されるように。

エグゼキュータ

クエリ実行の最終ステップはエグゼキュータによって行われます。エグゼキュータはクエリパイプラインを受け取り、それを実行します。SELECTINSERT、または INSERT SELECT を行うかどうかに応じて異なる種類のエグゼキュータがあります。