EXPLAIN

EXPLAINステートメントは、クエリを実行せずにクエリの実行プランを示します。クエリを実行するEXPLAIN ANALYZEによって補完されます。 EXPLAINの出力が期待される結果と一致しない場合は、クエリ内の各テーブルでANALYZE TABLEを実行することを検討してください。

ステートメントDESCDESCRIBEは、このステートメントの別名です。 EXPLAIN <tableName>の代替使用法はSHOW [FULL] COLUMNS FROMの下に文書化されています。

TiDB はEXPLAIN [options] FOR CONNECTION connection_idステートメントをサポートしています。ただし、このステートメントは MySQL のEXPLAIN FORステートメントとは異なります。詳細については、 EXPLAIN FOR CONNECTIONを参照してください。

あらすじ

ExplainSym
EXPLAINDESCRIBEDESC
ExplainStmt
ExplainSymTableNameColumnNameANALYZEExplainableStmtFORCONNECTIONNUMFORMAT=stringLitExplainFormatTypeFORCONNECTIONNUMExplainableStmt
ExplainableStmt
SelectStmtDeleteFromStmtUpdateStmtInsertIntoStmtReplaceIntoStmtUnionStmt

EXPLAIN出力形式

ノート:

MySQL クライアントを使用して TiDB に接続する場合、出力結果を改行なしでより明確に読み取るには、 pager less -Sコマンドを使用できます。次に、 EXPLAINの結果が出力されたら、キーボードの右矢印ボタンを押して、出力を水平方向にスクロールできます。

現在、TiDB のEXPLAINidestRowstaskaccess objectoperator infoの 5 つの列を出力します。実行計画の各演算子はこれらの属性によって記述され、 EXPLAINの出力の各行は演算子を記述します。各属性の説明は次のとおりです。

属性名説明
IDオペレーター ID は、実行計画全体におけるオペレーターの固有 ID です。 TiDB 2.1 では、ID はオペレーターのツリー構造を表示するようにフォーマットされます。子ノードから親ノードにデータが流れます。オペレーターごとに 1 つだけの親ノード。
estRowsオペレーターが出力すると予想される行数。この数は、統計とオペレーターのロジックに従って推定されます。 estRowsは、以前のバージョンの TiDB 4.0 ではcountと呼ばれていました。
仕事オペレーターが属するタスクのタイプ。現在、実行計画は 2 つのタスクに分かれています。tidb-server で実行されるrootタスクと、TiKV または TiFlash で並行して実行されるcopタスクです。タスク レベルでの実行計画のトポロジは、ルート タスクの後に多数の警官タスクが続くというものです。 root タスクは、cop タスクの出力を入力として使用します。 cop タスクは、TiDB が TiKV または TiFlash にプッシュするタスクを指します。各警官タスクは TiKV クラスターまたは TiFlash クラスターに分散され、複数のプロセスによって実行されます。
アクセス オブジェクトオペレーターがアクセスしたデータ項目情報。この情報には、 tablepartition 、およびindex (存在する場合) が含まれます。データに直接アクセスするオペレーターだけがそのような情報を持っています。
オペレーター情報オペレーターに関するその他の情報。各オペレーターのoperator infoつは異なります。以下の例を参照できます。

EXPLAIN SELECT 1;
+-------------------+---------+------+---------------+---------------+
| id                | estRows | task | access object | operator info |
+-------------------+---------+------+---------------+---------------+
| Projection_3      | 1.00    | root |               | 1->Column#1   |
| └─TableDual_4     | 1.00    | root |               | rows:1        |
+-------------------+---------+------+---------------+---------------+
2 rows in set (0.00 sec)
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, c1 INT NOT NULL);
Query OK, 0 rows affected (0.10 sec)
INSERT INTO t1 (c1) VALUES (1), (2), (3);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
EXPLAIN SELECT * FROM t1 WHERE id = 1;
+-------------+---------+------+---------------+---------------+
| id          | estRows | task | access object | operator info |
+-------------+---------+------+---------------+---------------+
| Point_Get_1 | 1.00    | root | table:t1      | handle:1      |
+-------------+---------+------+---------------+---------------+
1 row in set (0.00 sec)
DESC SELECT * FROM t1 WHERE id = 1;
+-------------+---------+------+---------------+---------------+
| id          | estRows | task | access object | operator info |
+-------------+---------+------+---------------+---------------+
| Point_Get_1 | 1.00    | root | table:t1      | handle:1      |
+-------------+---------+------+---------------+---------------+
1 row in set (0.00 sec)
DESCRIBE SELECT * FROM t1 WHERE id = 1;
+-------------+---------+------+---------------+---------------+
| id          | estRows | task | access object | operator info |
+-------------+---------+------+---------------+---------------+
| Point_Get_1 | 1.00    | root | table:t1      | handle:1      |
+-------------+---------+------+---------------+---------------+
1 row in set (0.00 sec)
EXPLAIN INSERT INTO t1 (c1) VALUES (4);
+----------+---------+------+---------------+---------------+
| id       | estRows | task | access object | operator info |
+----------+---------+------+---------------+---------------+
| Insert_1 | N/A     | root |               | N/A           |
+----------+---------+------+---------------+---------------+
1 row in set (0.00 sec)
EXPLAIN UPDATE t1 SET c1=5 WHERE c1=3;
+---------------------------+---------+-----------+---------------+--------------------------------+
| id                        | estRows | task      | access object | operator info                  |
+---------------------------+---------+-----------+---------------+--------------------------------+
| Update_4                  | N/A     | root      |               | N/A                            |
| └─TableReader_8           | 0.00    | root      |               | data:Selection_7               |
|   └─Selection_7           | 0.00    | cop[tikv] |               | eq(test.t1.c1, 3)              |
|     └─TableFullScan_6     | 3.00    | cop[tikv] | table:t1      | keep order:false, stats:pseudo |
+---------------------------+---------+-----------+---------------+--------------------------------+
4 rows in set (0.00 sec)
EXPLAIN DELETE FROM t1 WHERE c1=3;
+---------------------------+---------+-----------+---------------+--------------------------------+
| id                        | estRows | task      | access object | operator info                  |
+---------------------------+---------+-----------+---------------+--------------------------------+
| Delete_4                  | N/A     | root      |               | N/A                            |
| └─TableReader_8           | 0.00    | root      |               | data:Selection_7               |
|   └─Selection_7           | 0.00    | cop[tikv] |               | eq(test.t1.c1, 3)              |
|     └─TableFullScan_6     | 3.00    | cop[tikv] | table:t1      | keep order:false, stats:pseudo |
+---------------------------+---------+-----------+---------------+--------------------------------+
4 rows in set (0.01 sec)

出力の内容と形式を指定するには、 EXPLAINステートメントでFORMAT = xxx構文を使用できます。

FORMAT in EXPLAINを指定しない場合、またはFORMAT = "row"を指定する場合、 EXPLAINステートメントは結果を表形式で出力します。詳細については、 クエリ実行計画を理解するを参照してください。

FORMAT = "brief" in EXPLAINを指定すると、出力のオペレーター ID は、 FORMATを指定しない場合に比べて単純化されます。

EXPLAIN FORMAT = "brief" DELETE FROM t1 WHERE c1 = 3;
+-------------------------+---------+-----------+---------------+--------------------------------+
| id                      | estRows | task      | access object | operator info                  |
+-------------------------+---------+-----------+---------------+--------------------------------+
| Delete                  | N/A     | root      |               | N/A                            |
| └─TableReader           | 0.00    | root      |               | data:Selection                 |
|   └─Selection           | 0.00    | cop[tikv] |               | eq(test.t1.c1, 3)              |
|     └─TableFullScan     | 3.00    | cop[tikv] | table:t1      | keep order:false, stats:pseudo |
+-------------------------+---------+-----------+---------------+--------------------------------+
4 rows in set (0.001 sec)

MySQL 標準の結果形式に加えて、TiDB は DotGraph もサポートしており、次の例のようにFORMAT = "dot"を指定する必要があります。

create table t(a bigint, b bigint);
desc format = "dot" select A.a, B.b from t A join t B on A.a > B.b where A.a < 10;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| dot contents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
digraph Projection_8 {
subgraph cluster8{
node [style=filled, color=lightgrey]
color=black
label = "root"
"Projection_8" -> "HashJoin_9"
"HashJoin_9" -> "TableReader_13"
"HashJoin_9" -> "Selection_14"
"Selection_14" -> "TableReader_17"
}
subgraph cluster12{
node [style=filled, color=lightgrey]
color=black
label = "cop"
"Selection_12" -> "TableFullScan_11"
}
subgraph cluster16{
node [style=filled, color=lightgrey]
color=black
label = "cop"
"Selection_16" -> "TableFullScan_15"
}
"TableReader_13" -> "Selection_12"
"TableReader_17" -> "Selection_16"
}
 |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

dotのプログラム ( graphvizパッケージ内) がコンピューターにインストールされている場合、次の方法を使用して PNG ファイルを生成できます。

dot xx.dot -T png -O

The xx.dot is the result returned by the above statement.

dotのプログラムがコンピューターにインストールされていない場合は、結果をこのウェブサイトにコピーしてツリー図を取得します。

Explain Dot

MySQL の互換性

  • EXPLAINの形式と TiDB での潜在的な実行計画の両方が、MySQL とはかなり異なります。
  • TiDB はFORMAT=JSONまたはFORMAT=TREEのオプションをサポートしていません。

EXPLAIN FOR CONNECTION

EXPLAIN FOR CONNECTIONは、接続で現在実行されている SQL クエリまたは最後に実行された SQL クエリの実行計画を取得するために使用されます。出力形式はEXPLAINと同じです。ただし、TiDB でのEXPLAIN FOR CONNECTIONの実装は、MySQL での実装とは異なります。それらの違い (出力形式を除く) は次のとおりです。

  • MySQL は実行中のクエリ プランを返しますが、TiDB は最後に実行されたクエリ プランを返します。
  • MySQL では、ログイン ユーザーがクエリ対象の接続と同じである必要があります。そうでない場合、ログイン ユーザーはPROCESS権限を持っています。一方、TiDB では、ログイン ユーザーがクエリ対象の接続と同じである必要があります。そうでない場合、ログイン ユーザーはSUPER権限を持っています。

こちらもご覧ください

エコシステム
TiDB
TiKV
TiSpark
Chaos Mesh
© 2022 PingCAP. All Rights Reserved.