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を指定しない場合は、すべてのパスが実行されます。single_record– 整形されたクエリを、行ごとに1レコードではなく単一の複数行レコードとして返します。デフォルト:1(explain_syntax_single_record設定で制御) 。従来の1行1レコード出力に戻すには、0を設定するか、explain_syntax_single_record = 0を設定します (グローバルまたはクエリごとのSETTINGS内) 。または、compatibilityを26.8より前の任意のバージョンに設定します。
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。matches—EXPLAIN ANALYZEでは、結合による出力だけではこれらの数値を導出できない場合に、matched、match rate、fanoutメトリクスに必要な追加の記録処理を join ステップで行います。導出できる場合は、このオプションなしで報告されます。join ステップを参照してください。デフォルト: 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で設定されたクエリ処理スレッドの最大数
Join ステップ
EXPLAIN ANALYZE は各側の参加行 (Left と Right) を出力し、その後に join の実装固有の行を出力します。Left と Right は、論理的な SQL の左右に対応します。ほとんどの場合、Left は join のプローブ側、Right はビルド側にもなります。ただし、join の実行中に swap が発生する可能性があるため、常にそうとは限りません。join_algorithm のすべての値 (hash、parallel_hash、grace_hash、partial_merge、full_sorting_merge、parallel_full_sorting_merge、direct) に対応しています。また、この設定では選択できない 2 つの実装、すなわち CROSS または COMMA join、キーの等価条件を含まない ON 句、および Join テーブルエンジンも対象です。ほとんどの実装では両側が報告されますが、マテリアライズする側のみを報告するものもあります (たとえば、direct は Left: のみを出力します) 。
各側の行は同じ形式です。
EXPLAIN ANALYZE は以下を報告します。
rows <rows>— 結合処理を通過したその側の行の総数。matched <matched_rows>— もう一方の側で少なくとも1つの結合相手が見つかった、その側の行数。これはキーではなく行を数えます。キーが右側に3回出現して一致した場合、右側の3行すべてが一致した行としてカウントされます。match rate <match_rate>%— 一致したその側の行の割合。100 * <matched_rows> / <rows>として算出されます。fanout <fanout>— その側で一致した行1行あたりが平均して生成する出力行数。
0 ではなく not collected として報告されます。match rate と fanout は matched から導出されるため、matched がない側では、3つすべてが not collected として報告されます。
ファンアウト
fanout は行数の増加倍率を示します。
NULL で埋められた出力行が 1 行生成されます。これらの行は比率を薄めないよう差し引かれます。このような行が存在するのは保持側のみです。RIGHT と FULL では右側、LEFT と FULL では左側になります。
fanout = 0— 一致した行からは出力行がまったく生成されません。これはANTIjoin の動作であり、相手が見つからなかった行のみを出力します。fanout = 1— 明確な 1:1 join です。一致した各行から、ちょうど 1 行の出力行が生成されます。fanout > 1— 1:N join です。もう一方の側の重複キーによって行数が増加しました。両側で同時に大きな値になる場合は、意図しない Cartesian 的な行数の急増を示します。
数値に matches = 1 が必要な場合
EXPLAIN ANALYZE で報告されます。残りは、結合が通常は行わない追跡処理を必要とするため、EXPLAIN ANALYZE matches = 1 でのみ報告されます。どれが該当するかはアルゴリズムによって異なり、hash ファミリーでは次の 2 つです。
- 一致したすべての右行に印を付ける必要がある、
ALL INNERとALL LEFTの右側。 ALL LEFTとALL FULLの左側。ただし、クエリが右テーブルから何も選択せず、ONセクションが単純なキーの等価条件である場合に限ります。それ以外の場合、プローブはすでに 一致した左行を記録します。これは右カラムをマテリアライズするため、または残余条件を評価するためです。 そのため、このオプションがなくてもカウントは正確です。
partial_merge では、同じ理由で 4 種類の ALL の右側に必要です。
full_sorting_merge と parallel_full_sorting_merge では、ANY 種類の両方の側に必要です。
ALL 種類では何も必要ありません。
追加の追跡処理にはコストがかかり、計測精度に影響します。そのため、このオプションはデフォルトで無効になっています。処理はプローブループ内で実行され、出力行数に応じて増加します。左行と右行が相手側で正確に何件一致したかを知る必要がある場合は、
matches = 1 を使用してください。matches = 1 を指定しても、すべての組み合わせで収集できるようになるわけではありません。結合がどちらの側を報告できるかは、その結合がいずれにせよ実行する必要がある処理によるため、種類や厳密性だけでなくアルゴリズムにも依存します。
Hash ファミリー。 hash、parallel_hash、grace_hash は常に同じ結果になります。
結合がハッシュテーブル内でキーごとに 1 行だけを保持する場合、右側は収集できません。これは
ANY、SEMI、ANTI 結合で行われます。重複する右行は保存されないため、カウントできません。別の左行によってすでに相手が確保されている左行の出力を結合が抑制する場合、左側は収集できません。この場合、出力される行数は一致した行数より少なくなります。
any_join_distinct_right_table_keys を有効にすると、ANY は以前の RightAny セマンティクスに切り替わります。このセマンティクスでは左行ごとに 1 行が出力されるため、両方のカウントが保持されます。その場合、ANY RIGHT と ANY FULL は両方の側を報告し、ANY INNER は SEMI LEFT に書き換えられます。
Join テーブルエンジンも同じ表に従い、エンジンで宣言された種類と厳密性を使用します。Join(ALL, INNER, …) は両方の側を報告し、Join(ANY, LEFT, …) はどちらも報告しません。
マージアルゴリズム。 full_sorting_merge と parallel_full_sorting_merge は、4 種類の ALL、ANY INNER、ANY LEFT、ANY RIGHT、ASOF、ASOF LEFT を受け入れます。ASOF と ASOF LEFT を除くすべての種類で両方の側を報告します。これらでは右側が not collected になります。また、matches = 1 も不要です。2 つのソート済み入力を走査し、処理中に等しい範囲にあるすべての行を確認するため、後から再構築する必要がないからです。
partial_merge は ALL INNER、ALL LEFT、ALL RIGHT、ALL FULL、ANY INNER、ANY LEFT、SEMI LEFT を受け入れます。4 種類の ALL では両方の側を報告しますが、右側には matches = 1 が必要です。ANY INNER、ANY LEFT、SEMI LEFT では右側が not collected になります。
direct。 左側のみです。右側は行としてマテリアライズされないキー・バリューストアであるため、Right: 行自体がありません。
CROSS、COMMA、定数の ON。 前述のとおり、どちらの側も報告されません。
両方のアルゴリズムが数値を報告する場合、その値は一致します。マージアルゴリズムは単により多くの情報を持っているだけで、何を一致とみなすかについて見解が異なるわけではありません。
アルゴリズム固有の行
hash および parallel_hash JOIN、ならびに Join テーブルエンジンでは、Hash table: 行に右テーブルから構築されたハッシュテーブルの情報が表示されます。
unique keys <unique_keys>— ビルドフェーズ中にハッシュテーブルに格納された一意のキーの数。memory <peak_memory>— ビルドフェーズ中にハッシュテーブルが使用したピークメモリ。
grace_hash join では、Hash table: 行に、join がメモリ制限にどのように適応したかも表示されます。また、Spill: 行には、データがディスクにスピルされたかどうかが表示されます。
buckets <buckets>— 実行終了時点で Grace Hash Join に含まれるバケット数です。常に2のべき乗になります。rehashes <rehashes>— メモリ制限内に収めるために、バケット数を 2 倍にする必要があった回数です。Spill:— ディスクへのスピリングが発生したかどうかを示すyes/noフラグです。発生した場合、left spilled <left_spilled_bytes>とright spilled <right_spilled_bytes>は、それぞれ左側 (probe) と右側 (build) でスピリングされた圧縮バイト数を示します。スピリングが発生しなかった場合、この行は単にSpill: noとなります。
partial_merge 結合では、Right: 行に右テーブルのバッファリング方法とソート方法に関する追加情報が含まれ、ソート時間は Stage (build) 行と Stage (probe) 行に表示されます。
size <right_size>— 右テーブルのブロックのメモリ使用量。blocks <right_blocks>— 右テーブルがバッファリングされたブロック数。storage <in-memory|external>— 右テーブルがメモリに収まったか (in-memory) 、またはディスクにスピルする必要があったか (external) 。externalの場合、追加のspilled <spilled_bytes>にディスクに書き込まれた圧縮バイト数が表示されます。sort time <sort_time>— 右テーブルのソート (build ステージ) と、受信した各左ブロックのソート (probe ステージ) に費やされた時間。sort share <sort_share>%— ステージのtimeの割合がクエリ全体の実行時間に占める割合であるのに対し、sort timeがそのステージ自体のビジー時間 (各プロセッサの経過時間の合計) に占める割合。
full_sorting_merge join では、共通の Left: 行と Right: 行のみが出力されます。
direct join では、右側は行としてマテリアライズされず直接ルックアップされるキー・バリューストアであるため、Left: 行のみが出力されます。
CROSS または COMMA join、およびキーの等価条件を含まない任意の ON セクションでは、Buffer: 行に右テーブルがメモリ内でどのように保持されたかが示され、Spill: 行にディスクにスピルされたかどうかが表示されます。
memory <peak_memory>— バッファリングされた右テーブルが使用したピークメモリ。compressed <yes|no>— バッファリングされたブロックが少なくとも1つ圧縮されているかどうか。圧縮されている場合、reader は保存されているすべてのブロックを展開します。Spill:—grace_hashと同じyes/noフラグで、right spilled <right_spilled_bytes>はディスクに書き込まれた圧縮バイト数を示します。
matched not collected が報告されます。定数の predicate では、すべての左行がすべての右行と組み合わされるか、まったく組み合わされないかのいずれかとなるため、個々のどの行が一致したかを特定することはできません。
Join テーブルエンジンとの join では、事前構築済みテーブルを説明する Hash table: 行とともに、両側が報告されます。右側では、クエリごとの build の行数ではなく、エンジンに格納されている行数がカウントされます。
プロセッサごとの時間
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
検証は完全ではないため、クエリが成功しても、そのオーバーライドが問題を引き起こさないことは保証されません。