EXPLAIN ステートメントの概要
-
接続クエリの実行プランでは、各テーブルはレコードに対応し、これらのレコードの id 列の値は同じです。
-
サブクエリを含む実行プランでは、各選択キーワードは一意の ID 値に対応します。
-
ドライブテーブル: 前面に表示されるテーブル。
-
駆動テーブル: 後に表示されるテーブル。
EXPLAINの各フィールドの詳細説明
1. select_type の値は次のとおりです。
-
主要な
-
連合
-
UNION RESULT
UNION
: MySQL は、クエリの重複排除を完了するために一時テーブルの使用を選択します。 -
SUBQUERY : サブクエリを含むクエリ ステートメントを対応する半結合形式に変換できず、サブクエリが無関係なサブクエリであり、クエリ オプティマイザがサブクエリを実体化することによってサブクエリを実行することを決定した場合、 の
selct_type
値でSUBQUERY
。 -
DEPENDENT SUBQUERY : サブクエリを含むクエリ ステートメントを対応する半結合形式に変換できず、サブクエリが相関サブクエリである場合、 の
selct_type
値は ですDEPENDENT SUBQUERY
。 -
従属組合
-
DERIVED : 派生テーブルを含むクエリでは、クエリを実体化された派生テーブルとして実行します。
-
MATERIALIZED : クエリ オプティマイザーがサブクエリを含むステートメントを実行するとき、サブクエリを実体化し、それを外部クエリに接続することを選択します。その後、サブクエリの対応する値は次のようになります
selct_type
。MATERIALIZED
-
UNCACHEABLE SUBQUERY : 一般的には使用されません
-
キャッシュできない UNION : 一般的には使用されません
2. type value (アクセス方法を示す)
完全なアクセス方法は、system、const、eq_ref、ref、fulltext、ref_or_null、index_merge、unique_subquery、index_subquery、range、index、ALL などです。
-
system : テーブルにレコードが 1 つだけあり、テーブルで使用されるストレージ エンジン (MyISAM、MEMORY など) の統計データが正確な場合、テーブルのアクセス方法は system です。
-
const : 主キーまたは一意の副インデックス列に基づく定数による等価一致を実行する場合、単一テーブルのアクセス方法は const です。好き:
EXPLAIN SELECT * FROM s1 WHERE id = 5;
-
eq_ref : 駆動テーブルが主キーを介してアクセスされる場合、または NULL 値の格納を許可しない唯一の副インデックス列が結合インデックスである場合、すべてのインデックス列が等しいかどうかを比較する必要があります)、アクセス方法駆動テーブルのは eq_ref です。例えば
EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;
このとき、s1の型はALL、s2の型はeq_refとなる。 -
ref : 通常のセカンダリ インデックス列と定数間の等価一致によってテーブルがクエリされる場合、テーブルのアクセス方法は ref である可能性があります。
-
fulltext : 全文インデックス
-
ref_or_null : 通常のセカンダリインデックス列に対して等価マッチングが行われ、インデックス列の値が NULL 値になる可能性がある場合、テーブルのアクセス方法は ref_or_null になる可能性があります。
-
Index_merge : 通常、単一のインデックスに対してスキャン間隔のみが生成されます。インデックスのマージ。
-
unique_subquery : 2 つのテーブル結合における駆動テーブルの eq_ref アクセス方法と同様に、 unique_subquery は IN サブクエリを含む一部のクエリ ステートメントを対象としています。クエリ オプティマイザーが IN サブクエリを EXISTS サブクエリに変換することを決定し、変換後、サブクエリで主キーまたは同等の一致のために NULL 値の格納を許可しない一意のセカンダリ インデックスを使用できる場合、型列はサブクエリの unique_subquery の値。
-
Index_subquery : unique_subquery と似ていますが、サブクエリ内のテーブルにアクセスするときに通常のインデックスが使用される点が異なります。
-
範囲:
-
インデックスを使用して、いくつかの単一ポイントのスキャン間隔のレコードを取得します (たとえば、
explain select * from s1 where key1 in ('a', 'b', 'c');
このとき、テーブル s1 の type 列の値は range です)。 -
一定の範囲のスキャン間隔(たとえば、
explain select * from s1 where key1 > 'a' and key1 < 'b';
このとき、テーブルs1のtype列の値はrange)のレコードを取得するために使用されます。
- インデックス:
-
インデックス カバレッジを使用し、すべてのインデックス レコードをスキャンする必要があります。たとえば、
explain select key_part2 from s1 where key_part3 = 'a';
このとき、テーブル s1 の type 列の値は、index です。- 分析: key_part2 列と key_part3 列は結合インデックス idx_key_part に含まれていますが、検索条件 key_part3='a' は、スキャンするレコード数を減らすための適切なスキャン間隔を形成できず、全体のレコードのみをスキャンできます。 idx_key_part インデックスなので実行 計画型カラムの値はインデックスです。
-
特殊: InnoDB ストレージ エンジンの場合、テーブル全体のスキャンが必要で、主キーをソートする必要がある場合 ( など)、
explain select * from s1 order by id;
このときの type カラムの値もインデックスになります。
- ALL : フルテーブルスキャン。
3. possible_keys 和キー
EXPLAIN ステートメントによって出力された実行計画では、
-
possible_keys 列: 特定のクエリ ステートメント内の特定のテーブルに対して単一テーブル クエリを実行するときに、どのインデックスを使用できるかを示します。
-
キー列: 実際に使用されるインデックスを示します。(クエリ オプティマイザーは、さまざまなインデックスを使用するコストを計算した後、インデックスを使用してクエリを実行することを決定します)
4.key_len
key_len 値は次の 3 つの部分で構成されます。
-
この列の実際のデータが占める記憶領域の最大長。
-
列に NULL 値を格納できる場合、key_len の値は、列の実際のデータが占める最大記憶領域長に基づいて 1 バイト追加されます。
-
可変長列の場合、可変長列の実際のデータが占める記憶領域の長さを格納するための 2 バイトの領域があり、key_len の値は元の値に 2 バイトを追加します。
5.参考文献
アクセス方法が const、eq_ref、ref、ref_or_null、unique_subquery、index_subquery のいずれかの場合、ref 列はインデックス列に相当するもの、たとえば定数または特定の列のみを示します。
6.行
rows列:
-
テーブルの推定行数を表します (フルテーブルスキャン)。
-
スキャンされることが予想されるインデックス行の数を表します (インデックスを使用してクエリを実行します)。
7. フィルタリング済み
接続クエリのコストを分析する際に、MySQL が駆動テーブルのファンアウトを計算するときに採用する戦略である条件フィルタリング (条件付きフィルタリング) の概念が提案されました。
-
単一のテーブル クエリを実行するためにフル テーブル スキャンが使用される場合、駆動テーブルのファンアウトを計算するときに、すべての検索条件を満たすレコードの数を見積もる必要があります。
-
インデックスを使用して単一テーブル スキャンを実行する場合、駆動テーブルのファンアウトを計算するときに、インデックス スキャン間隔を構成する検索条件以外の他の検索条件を満たすレコードの数を見積もる必要があります。
小さな例を挙げると、接続クエリでは、駆動テーブルの行列 x 駆動テーブルのフィルターされた列 = 駆動テーブルのファンアウト値 (駆動テーブルで実行するクエリの数)
8. おまけ
「追加」列は、いくつかの追加情報を説明するために使用されます。たくさんありますが、一般的なものは次のとおりです。
-
テーブルが使用されていません: クエリ ステートメントに FROM 句がありません。
-
不可能な WHERE : WHERE 句は常に FALSE です。
-
一致する最小/最大行がありません: クエリ リストに MIN または MAX 集計関数があっても、WHERE 句の検索条件を満たさない場合、この追加情報が求められます。
-
インデックスの使用: カバーインデックスを使用してクエリを実行します。
-
インデックス条件の使用: 一部の検索条件にはインデックス列が表示されますが、スキャン間隔を形成するための境界条件として使用することはできません。つまり、スキャンする必要があるレコードの数を減らすために使用することはできません。
-
where を使用する: 特定の検索条件をサーバー層で判断する必要があります。
-
filesort の使用: filesort を使用してクエリを実行します。(ファイルソート: メモリ上またはディスク上でソートする方法)
-
一時テーブルの使用: クエリを実行するための内部一時テーブルを作成します。
イースターエッグ - 拡張された EXPLAIN
EXPLAIN ステートメントを使用してクエリの実行計画を表示した後、SHOW WARNINGS ステートメントを使用してクエリの実行計画に関連する拡張情報を表示することもできます。