EXPLAIN の種類
AST— 抽象構文木。SYNTAX— AST レベルでの最適化後のクエリテキスト。QUERY TREE— クエリツリー レベルでの最適化後のクエリツリー。PLAN— クエリ実行プラン。PIPELINE— クエリ実行パイプライン。ANALYZE— クエリを実行し、計測されたランタイムメトリクスを実行計画に注釈として付加します。ESTIMATE— クエリの処理中にテーブルから読み取ると見積もられる行数、マーク数、パーツ数。TABLE OVERRIDE— テーブル関数のスキーマに対するテーブルオーバーライドの検証済み結果。
EXPLAIN AST
SELECT だけでなく、あらゆる種類のクエリをサポートします。
設定:
graph– DOT グラフ記述言語で記述されたグラフとして AST を出力します。デフォルト: 0。
EXPLAIN SYNTAX
oneline– クエリを1行で表示します。デフォルト:0。run_query_tree_passes– クエリツリーをダンプする前にクエリツリーパスを実行します。デフォルト:0。query_tree_passes–run_query_tree_passesが設定されている場合、実行するパス数を指定します。query_tree_passesを指定しない場合は、すべてのパスが実行されます。
Query
Response
run_query_tree_passes を指定した場合:
Query
Response
EXPLAIN QUERY TREE
run_passes— クエリツリーをダンプする前に、すべてのクエリツリーパスを実行します。デフォルト:1。dump_passes— クエリツリーをダンプする前に、使用されるパスの情報をダンプします。デフォルト:0。passes— 実行するパスの数を指定します。-1に設定すると、すべてのパスを実行します。デフォルト:-1。dump_tree— クエリツリーを表示します。デフォルト:1。dump_ast— クエリツリーから生成されたクエリ AST を表示します。デフォルト:0。
EXPLAIN PLAN
optimize— プランを表示する前に、クエリプランの最適化を適用するかどうかを制御します。デフォルト: 1。header— ステップの出力ヘッダーを表示します。デフォルト: 0。description— ステップの説明を表示します。デフォルト: 1。indexes— 使用された索引、フィルタリングされたパーツ数、および適用された各索引についてフィルタリングされたグラニュール数を表示します。デフォルト: 0。MergeTree テーブルでサポートされています。ClickHouse >= v25.9 以降、このステートメントが適切な出力を示すのは、SETTINGS use_query_condition_cache = 0, use_skip_indexes_on_data_read = 0とともに使用した場合のみです。projections— 解析されたすべてのプロジェクションと、プロジェクションの主キー条件に基づくパーツレベルのフィルタリングへの影響を表示します。各プロジェクションについて、このセクションには、プロジェクションの主キーを使って評価されたパーツ数、行数、マーク数、範囲数などの統計が含まれます。また、このフィルタリングにより、プロジェクション自体を読み取ることなくスキップされた data parts の数も表示します。プロジェクションが実際に読み取りに使用されたのか、それともフィルタリングのために解析されただけなのかは、descriptionフィールドで判別できます。デフォルト: 0。MergeTree テーブルでサポートされています。actions— ステップの actions に関する詳細情報を表示します。デフォルト: 1。sorting— ソート済みの出力を生成する各プランステップについて、ソートの説明を表示します。デフォルト: 0。keep_logical_steps— joins について、物理的な join 実装に変換せずに、論理プランステップを保持します。デフォルト: 0。json— クエリプランのステップを JSON フォーマットの 1 行として出力します。デフォルト: 0。不要なエスケープを避けるため、TabSeparatedRaw (TSVRaw) フォーマットの使用を推奨します。input_headers— ステップの入力ヘッダーを表示します。デフォルト: 0。主に、入力ヘッダーと出力ヘッダーの不一致に関する問題をデバッグする開発者にのみ有用です。column_structure— ヘッダー内のカラム構造を、名前と型に加えて表示します。デフォルト: 0。主に、入力ヘッダーと出力ヘッダーの不一致に関する問題をデバッグする開発者にのみ有用です。distributed— 分散テーブルまたは並列レプリカについて、リモートノードで実行されるクエリプランを表示します。jsonと同時にはサポートされません。デフォルト: 0。compact— 有効にすると、プランから expression ステップと詳細な action 情報 (入力、関数、別名、出力位置) を非表示にします。actions = 1の場合にのみ効果があります。デフォルト: 1。pretty— インデントの代わりに罫線文字 (├──、└──、│) を使ってプランツリーを表示し、階層構造を視覚化します。さらに、join ステップのプロパティもインラインで整形して表示します。デフォルト: 1。
デフォルトでは、
explain_query_plan_default = 'pretty' であるため、actions、compact、pretty は 1 に初期化され、プランはコンパクトで見やすく、action 注釈付きの形式で描画されます。EXPLAIN ステートメントでこれらのオプションのいずれかを明示的に指定した場合 (たとえば、EXPLAIN actions = 0, compact = 0, pretty = 0 SELECT ...) は、常にその指定がデフォルトを上書きします。ClickHouse 26.7 より前では、actions、compact、pretty のデフォルトは 0 でした。その出力は、explain_query_plan_default = 'legacy' を設定する (グローバル、またはクエリごとの SETTINGS で設定する) か、compatibility を 26.7 より古い任意のバージョンに設定することで、引き続き取得できます。json と distributed オプションでは、explain_query_plan_default = 'pretty' の場合でも、pretty のデフォルト (actions、compact、pretty) は有効になりません。出力に action の詳細を含めるには、actions = 1 を手動で設定してください。Step およびクエリのコスト見積もりはサポートされていません。
json = 1 の場合、クエリプランは JSON フォーマットで表されます。各ノードは辞書で、常に Node Type、Node Id、Plans のキーを持ちます。Node Type はステップ名を表す文字列で、Node Id は一意のステップ識別子です (数値の接尾辞が付いたステップ名。例: Union_10) 。Plans は子ステップの説明を含む配列です。その他の任意のキーは、ノードの種類や設定に応じて追加されることがあります。
例:
description = 1 の場合、Description キーがステップに追加されます。
header = 1 の場合、Header キーがカラムの配列としてステップに追加されます。
例:
indexes = 1 の場合、Indexes キーが追加されます。これには、使用された索引の配列が含まれます。各索引は JSON で記述され、Type キー (文字列 Partition Min-Max、Partition、Statistics、PrimaryKey または Skip) と、必要に応じて以下のキーを持ちます。
Name— 索引名 (現在はSkip索引でのみ使用) 。Keys— 索引で使用されるカラムの配列。Condition— 使用された条件。Description— 索引の説明 (現在はSkip索引でのみ使用) 。Parts— 索引の適用後/適用前のパーツ数。Granules— 索引の適用後/適用前のグラニュール数。Ranges— 索引の適用後のグラニュール範囲数。
projections = 1 を指定すると、Projections キーが追加されます。これには、分析されたプロジェクションの配列が含まれます。各プロジェクションは、以下のキーを持つ JSON として記述されます:
Name— プロジェクション名。Condition— プロジェクションで使用された主キー条件。Description— プロジェクションの使用方法の説明 (例: パーツレベルのフィルタリング) 。Selected Parts— プロジェクションによって選択されたパーツ数。Selected Marks— 選択されたマーク数。Selected Ranges— 選択された範囲数。Selected Rows— 選択された行数。Filtered Parts— パーツレベルのフィルタリングによってスキップされたパーツ数。
actions = 1 の場合、追加されるキーはステップの種類によって異なります。
例:
compact = 0 かつ actions = 1 を指定すると、Expression ステップとともに式に関する詳細情報を確認できます:
distributed = 1 を指定すると、出力にはローカルのクエリプランだけでなく、リモートノードで実行されるクエリプランも含まれます。これは、分散クエリの分析やデバッグに役立ちます。
distributed は、pretty 出力ではリモート分片のプランがプランツリーに統合されないため、legacy (非pretty) 形式でのみ表示されます。このため、distributed を有効にすると、explain_query_plan_default の値に関係なく、pretty のデフォルト設定 (actions、compact、pretty) は自動的に無効になります。なお、actions=1 は手動で設定できます。また、distributed オプションは json と併用できません。pretty = 1 を指定すると、プランツリーはインデントの代わりに罫線文字で表示され、主要なステップの追加情報も表示されます:
- クエリ出力カラム はプランの先頭に表示されます。
- フィルタ、集約キー、ソートの説明、ウィンドウ関数内の 式 は、人が読める SQL 風の表記で表示されます (例:
greater(plus(a, 1), 5)ではなくa + 1 > 5) 。わかりやすさのため、内部カラム識別子のプレフィックス (__table1.など) は削除されます。 - ソースステップ (
ReadFromMergeTreeなど) には、その出力カラムが表示されます。 - フィルタステップ には、SQL 表記のフィルタ条件が表示されます。ランタイム join フィルタが存在する場合は、それらは別個に表示されます。
- 集約ステップ には、キーと、引数付きの集約関数 (例:
sum(c)、count()) が表示されます。 - タプルリテラルの IN set にはその値が表示され (大きな set の場合は切り詰められます) 、サブクエリベースの set には
subquery1、subquery2などのラベルが付き、Setengine tables 由来の set にはテーブル名が表示されます。 - join ステップ には、数学的記法を用いた join 関係、推定結果行数、 およびどの出力カラムが左側と右側のどちらに由来するかが表示されます。異なる join タイプを 表すために、次の記号が使用されます:
たとえば、
t1 ⟕ t2 はテーブル t1 と t2 の left join を意味します。
テーブル名の後の角括弧内の数値 (例: t1[100]) は、テーブル統計が利用可能な場合の
推定行数を示します。
pretty オプションは compact = 1 と組み合わせると効果的で、Expression ステップと詳細な action 情報が非表示になるため、プランが読みやすくなります。
JOINを使った詳しい例:
EXPLAIN PIPELINE
header— 各出力ポートのヘッダーを表示します。デフォルト: 0。graph— DOT グラフ記述言語で記述されたグラフを表示します。デフォルト: 0。compact—graph設定が有効な場合、compact モードでグラフを表示します。デフォルト: 1。compact_repeated_processor_chains— テキスト出力で、隣接して繰り返されるプロセッサチェーンを、チェーンを 1 つだけ表示して繰り返し回数を付けることでコンパクトにします。これにより、たとえば JOIN で同じチェーンが何度も現れる場合に、並列パイプラインが読みやすくなります。グラフ出力には影響しません。デフォルト: 0。
compact=0 かつ graph=1 の場合、プロセッサ名には一意のプロセッサ識別子を示す追加の接尾辞が含まれます。
例:
EXPLAIN ANALYZE
EXPLAIN ANALYZE は実際にクエリを実行し、結果の行を破棄したうえで、各ステップに実行時に実際に何が起きたかを注記として付けた、EXPLAIN PLAN と同じプランツリーを出力します。
設定:
EXPLAIN ANALYZE では、EXPLAIN PLAN と同じ表示オプションを使用できます (EXPLAIN PLAN セクションを参照) 。
header— EXPLAIN PLAN セクションを参照してください。description— EXPLAIN PLAN セクションを参照してください。projections— EXPLAIN PLAN セクションを参照してください。sorting— EXPLAIN PLAN セクションを参照してください。input_headers— EXPLAIN PLAN セクションを参照してください。column_structure— EXPLAIN PLAN セクションを参照してください。actions— EXPLAIN PLAN セクションを参照してください。デフォルト: 1。indexes— EXPLAIN PLAN セクションを参照してください。デフォルト: 1。compact— EXPLAIN PLAN セクションを参照してください。デフォルト: 1。pretty— EXPLAIN PLAN セクションを参照してください。デフォルト: 1。processors—EXPLAIN ANALYZEでは、各ステージについて、プロセッサごとの経過時間分布 (min、median、max、sum) を示す追加の行を出力します。並列プロセッサ間の負荷の偏りを見つけるのに役立ちます。デフォルト: 0。
EXPLAIN ANALYZE はラップされたクエリを実際に実行するため、いくつかの点で、そのクエリと同じように動作し、実行しない EXPLAIN 形式とは異なります。- クォータと制限。 クエリを直接実行した場合と同じ quotas
に対してカウントされ、同じ limits
(たとえば
query_selects、read_rows) の対象にもなります。プランニング中はクォータの対象外となるテーブル (system.oneなど) についてはカウントされません。 - 失敗したトランザクション。 すでに失敗している transaction
(
ROLLED_BACK) 内では、通常のSELECTと同様にINVALID_TRANSACTIONで拒否されます。 先にROLLBACKを実行してください。 - ストリーミング読み取り。 ストリーミング (
FROM ... STREAM) 読み取りに対しては、 そのような読み取りは完了しないため、NOT_IMPLEMENTEDで拒否されます。 - 分散クエリ。 distributed モードで実行される クエリではサポートされていません。
Time— 合計時間です。planning (つまり、plan の作成 + plan の最適化 + パイプラインの構築) フェーズと execution (パイプラインの実行) フェーズに分けて表示されます。Read— テーブルから読み取られた行数と非圧縮バイト数、および throughput です。これは通常のクエリのフッターで “Processed” として報告される数値と同じです。Peak memory— クエリが使用したピークメモリです。
I/O 行) 。時間と並列度は、ステップ内の各ステージごとに、その下のインデントされた行に報告されます。
rows <in> → <out>— ステップに入力された行数と、ステップから出力された行数です。(<selectivity>%) は、そのステップがデータをどの程度絞り込んだか (out/in) 、または増やしたかを示します。入力行数と出力行数が同じ場合、および入力行数が0の場合は表示されません。<bytes_in> → <bytes_out>— ステップ内を流れる非圧縮のインメモリバイト数です (両方ともゼロの場合は省略されます) 。time <t> (<share>%)— そのステージがアクティブだった実時間と、クエリ実行時間に占める割合です (つまり、build time は含みません) 。ステージやステップは同時実行されるため、この割合の合計が 100% を超えることがあります。parallelism <avg>/<max>— このステージ内で同時に動作していた CPU スレッド数の平均値と、そのステージで使用可能な最大値です。値が最大値に近いほど、そのステージは十分に並列化されていたことを示します。1 に近い場合は、ほぼ直列に実行されていたことを示します。Stage (<stage>)— ステージ名です。ステージが 1 つだけのステップでは、Stage (...)ラベルは付かず、時間の行が直接出力されます。複数のステージを持つステップでは、各ステージごとにラベル付きの行が 1 行ずつ出力されます。たとえばAggregatingではStage (partial aggregation)とStage (final aggregation)が表示され、ハッシュ結合ではStage (build)とStage (probe)が表示されます。
ClickHouse は、プランステップ内のタスク実行だけでなく、プランステップ自体の実行も並列化します。
parallelism メトリクスが反映するのは、このステップの処理だけです。他のステップも同時に実行されることがあるため、この数値から、このステップの並列度をクエリ全体と比較することはできません。parallelism の最大値は、次の 2 つのうち小さい方として計算されます。- プランステップ内のタスク総数
max_threadsで設定されたクエリ処理スレッドの最大数
processors = 1 の場合、各ステージの下に追加の行が出力され、そのステージのプロセッサごとの経過時間の分布が表示されます。
<n> はそのステージのプロセッサ数です。median と max の間に大きなギャップがある場合は、並列プロセッサ間で負荷に偏りがあることを示します。
EXPLAIN ESTIMATE
Query
Query
Response
EXPLAIN WHATIF
SELECT クエリにもたらす効果を見積もります。CREATE HYPOTHETICAL INDEX で 1 つ以上の候補を定義し、EXPLAIN WHATIF SELECT ... を実行すると、各候補について、適用可否、推定読み取りマーク数、推定バイト数、スキップ率を確認できます。
構文
empirical—1(デフォルト) では、スキップ率 (上限値) を測定するため、ベースラインで絞り込まれたグラニュールに対してメモリ内で索引を適用します。0ではその処理をスキップします。いずれの場合も、empiricalで結果が得られない場合 (無効になっている、または索引をメモリ内で評価できない場合) 、推定器はカラム STATISTICS にフォールバックし、それも利用できなければ、最終的に適用可否のみのサマリーにフォールバックします。
source— 推定値の算出方法を示します。empirical: ベースラインで pruned されたグラニュールを対象に、メモリ内で索引を構築し、その索引によってスキップされるグラニュール数を数えます。これは上限値です。制限事項についてはCREATE HYPOTHETICAL INDEXを参照してください。statistical: カラム STATISTICS から導出されます。empirical が無効化されている場合 (empirical = 0) 、または empirical で結果を生成できず、かつ関連するカラムにカラム STATISTICS が定義されている場合に使用されます。applicability_only: 索引は predicate に適用可能ですが、empirical と statistical のいずれでも結果を生成できなかったことを示します (たとえばempirical = 0でカラム STATISTICS が定義されていない場合) 。保守的な上限としてskip_ratio: 0.0%を返します。
sampled_parts/sampled_marks—<baseline-pruned> / <total in the table>。テーブル全体のうち、PK、partition、既存の索引による pruning を通過した割合、つまり仮想索引への入力となる部分を示します。est_bytes— 読み取られるバイト数の推定値です。テーブルの平均行サイズから導出されるため概算であり、ストレージや圧縮によって変動します。ベースラインの行はクエリが行を読み取る場合にのみ表示され、候補ごとの行はベースラインのバイト推定値がわかっている場合にのみ表示されます。
WHATIF と SELECT の間にインラインで記述します。SETTINGS キーワードはありません (これは、他の EXPLAIN バリアントでオプションを受け付ける方法と一致しています) 。
テーブルに仮想索引が定義されていない場合、EXPLAIN WHATIF は status: not_applicable を返し、作成を促すヒントを表示します。
結合行 (複数候補)
2 つ以上の候補が empirical で評価されると、EXPLAIN WHATIF は候補ごとの行の後に (combined: idx_a, idx_b, ...) という名前の追加ブロックを 1 つ付加します。これは、それらすべての索引を同時に持つ場合の総合的な効果を示します。実際の読み取りでは、あるグラニュールが保持されるのは、それが すべて のスキップ索引を通過した場合だけなので、結合推定値は各候補で生き残るグラニュールの積集合になります。したがって、この skip_ratio は少なくとも最良の単一候補と同等以上になります。相補的な索引は組み合わせることでより多くを prune し、冗長な索引では変化しません。
寄与するのは source: empirical の候補だけです。これは、結合された行が各 グラニュール ごとの生存集合の積集合を取って構築されるためです。statistical または applicability_only と推定された候補には グラニュール ごとのデータがないため除外されます。その結果、結合ブロックが表示されるのは少なくとも 2 つの候補が経験則ベースの推定を生成した場合だけで、それ以外の場合 (たとえば empirical = 0 の場合) には省略されます。その推定フィールドは、elapsed_us が 0 である点を除き、候補ごとの経験則ベースのブロックと同じです — 結合推定は候補ごとのスキャンから導出されるものであり、新たなスキャンではありません。合成された (combined: ...) という名前はレポート用ラベルにすぎず、force_data_skipping_indices では使用できません。
経験則ベースの例
minmax を使うと、100 個のマークを 1 個まで絞り込めます — skip_ratio: 99.0%。(est_bytes は平均行サイズに基づく推定値のため、正確な値は変動します。)
統計の例
カラム STATISTICSはデフォルトで無効になっています。statistical パスを試すには、まず対象のカラムでこれらを定義し、materialize mutation が完了するまで待ちます:
b < 10 のカラム STATISTICS における選択性 (10000 行中およそ 10 行) に基づくもので、skip_ratio の上限として報告されます。sampled_parts / sampled_marks はなく、データは読み取られていません。
どちらの方法も利用できない場合 (たとえば empirical = 0 で、かつカラム STATISTICS が定義されていない場合) 、推定器は source: applicability_only と保守的な skip_ratio: 0.0% を報告します。
EXPLAIN TABLE OVERRIDE
Query
Query
Response
検証は完全ではないため、クエリが成功しても、そのオーバーライドが問題を引き起こさないことは保証されません。