MySQL (上級・インタビュー) - (MySQL の最適化 1) 詳しい解説

目次

 1. EXPLAIN は何をしますか? EXPLAIN キーワードを使用して、オプティマイザによる SQL クエリ ステートメントの実行をシミュレートし、MySQL が SQL ステートメントをどのように処理するかを知ることができます。クエリ ステートメントまたはテーブル構造のパフォーマンスのボトルネックを分析します。

2. Explain の役割

3. 各フィールドの意味と機能を説明する 

3. SQLの実行順序

4. 人間の言葉で話す---各分野の事例分析の意味を説明する

4.1、ID

4.2、タイプの選択 

4.3、表

4.4、タイプ

4.5. possible_keys

4.6.

4.7. key_len

4.8. 参照

4.9. 行インデックスをクエリするときは、必要なレコードを読み取るために必要な行数を大まかに見積もります。

4.10. 余分な



 1. EXPLAIN は何をしますか?
   EXPLAIN キーワードを使用すると、オプティマイザによる SQL クエリ ステートメントの実行をシミュレートできるため、MySQL が SQL ステートメントをどのように処理するかを知ることができます。クエリ ステートメントまたはテーブル構造のパフォーマンスのボトルネックを分析します。

2. Explain の役割

もちろん、これにより、より適切な SQL ステートメントを作成し、クエリ速度を向上させることができます。実際には、端的に言えば、インデックスをできるだけ使用するクエリ SQL を記述し、クエリされるデータの総数をできるだけ少なくすることで、クエリ速度を向上させましょう。

 select+sql 文の前に Explain を追加すると、
(1) テーブルの読み取り順序 id (テーブルは id に対応するテーブル)
(2) データ読み取り操作の操作タイプ select type
( 3) 使用できるインデックス、 possible_keys
(4) 実際に使用されるインデックス、key
(5) テーブル間の参照、ref
(6) オプティマイザによってクエリされる各テーブルの行数、rows

3. 各フィールドの意味と機能を説明する 

Explain各フィールドの説明
シリアルナンバー フィールド名 フィールド関数の説明
1 ID 数字のグループを含むクエリのシーケンス番号は、クエリ内で選択句または操作テーブルが実行される順序を示します。
**両方の場合**
ID は同じですが、ID は上から下まで異なります。実行順序は
id値が大きいほど優先度が高くなります。
2 選択タイプ クエリ タイプ。主に、通常のクエリ、結合クエリ、サブクエリ、その他の複雑なクエリを区別するために使用されます。
1.シンプル- 単純な選択クエリ。クエリにはサブクエリまたは UNION が含まれません。
2.プライマリ- クエリに複雑なサブクエリ部分が含まれる場合、最も外側のクエリです。クエリはマークされます。
3.サブクエリ- select または where リストに含まれるサブクエリ。
4.派生- from リストに含まれるサブクエリは派生 (派生) としてマークされます。MySQL はこれらのサブクエリを再帰的に実行します。クエリと結果を一時テーブルに入れます。
5.ユニオン- 2 番目の選択が UNION の後に出現する場合、UNION としてマークされます。ユニオンが from 句のサブクエリに含まれる場合、外側の選択は派生としてマークされます 6 、ユニオンの結果:
UNION結果
3 テーブル 出力行によって参照されるテーブル
4 タイプ

接続タイプの表示、クエリで使用されているタイプの表示、最良から最悪のタイプへの並べ替え
1. system : テーブル (= システム テーブル) には 1 つの行しかありません。これは const 接続タイプの特殊なケースです。
2. const : インデックスを 1 回だけ検索できることを意味し、主キーまたは一意のインデックスを比較するために使用されます。データの 1 行のみが一致するため、主キーが where リストに配置されている場合、mysql はクエリを定数 3 に変換できます。
eq_ref :一意のインデックス スキャン。インデックス キーごとに、テーブル内の 1 つのレコードのみがそれに一致します。一意のインデックスまたは主キー スキャンで一般的に使用されます
4. ref : 非一意のインデックス スキャンは、単一の値に一致するすべての行を返します。これは本質的にインデックス アクセスです。単一の値に一致するすべての行が返され、多すぎる行が見つかる可能性があります。
5.範囲:指定された範囲の行のみを取得し、インデックスを使用して行を選択します。key列はどのインデックスが使用されているかを示しており、一般的にはwhere文のbetweenやinなどの範囲を指定したクエリになります。この範囲スキャンの
インデックス スキャンは、インデックス内の特定のポイントで開始され、フル テーブル スキャンを行わずに別のポイントで終了するため、フルテーブル スキャンよりも優れています。インデックスツリー。インデックス ファイルはデータ ファイルよりもはるかに小さいため、通常は他のファイルよりも高速です。7. all : テーブル全体を走査して一致する行を見つけます。

システム > const > eq_ref > ref > 範囲 > インデックス > すべて


注: 一般に、クエリが少なくとも範囲レベルに到達し、できれば ref に到達することが保証されます。

5 possible_keys MySQL がテーブルを検索するためにどのインデックスを使用できるかを示します (使用されているインデックスの可能性があります)。
6 MySQL が実際に使用することを決定したキー (インデックス)を表示しますインデックスが選択されていない場合、キーは NULL になります。クエリでカバリング インデックスが使用されている場合、インデックスはクエリの選択フィールドと重複します。
7 key_len インデックスで使用されるバイト数を表します。この列は、クエリで使用されるインデックスの長さを計算します。長さが短いほど、精度は損なわれませんキーが NULL の場合、長さは NULL になります。このフィールドは、実際に使用される長さではなく、インデックス フィールドの可能な最大長として示されています。
8 参照 インデックスのどの列が使用されているか(可能であれば定数)、インデックス列の値のクエリにどの列または定数が使用されているかを
9 テーブルの統計とインデックスの選択に基づいて、必要なレコードを見つけるために読み取る必要がある行数を大まかに見積もります。
10 余分な 他の列での表示には適さないが、非常に重要な追加情報が含まれています。
1. filesort の使用: mysql が外部インデックス ソートをデータに適用することを示します。テーブル内のインデックス順に読み取るのではなく。MySQL でソート操作を完了するためにインデックスを使用できないことは、「ファイル ソート」と呼ばれます
2.一時テーブルの使用: 中間結果の保存に一時テーブルが使用されます。MySQL は、クエリ結果をソートするときに一時テーブルを使用します。一般に、並べ替え順序およびグループ クエリのグループ化で使用されます。
3.インデックスの使用: 対応する選択操作で、テーブルのデータ行へのアクセスを回避するためにカバー インデックスを使用することを示します。where が同時に出現する場合は、テーブル名インデックスを使用してインデックス キー値の検索が実行されます。where が同時に出現しない場合は、クエリ アクションを実行する代わりに、テーブル名インデックスを使用してデータが読み取られます。
4. where の使用: where フィルタリングの使用を示します
。 5.結合バッファの使用: 接続キャッシュを使用します。
6.不可能な where : where 句の値は常に false であり、タプルの取得に使用できません
。 7.最適化されたテーブルを選択します。グループがない場合 by 句の場合、インデックスに基づいて Min および max 演算を最適化するか、MyISAM ストレージ エンジンのカウント (*) を最適化すると、実行段階まで計算を待つ必要がありません。クエリ実行プランの生成段階で完了します。
8.独特の: 個別の操作を最適化し、最初に一致するタプルを見つけた後、同じ値の検索を停止します。


 

3. SQLの実行順序

     SQL を最適化したい場合は、SQL の実行順序を明確に把握する必要がありますが、Explain! を使用すると、半分の労力で 2 倍の結果を得ることができます。

3.1. 完全な SQL ステートメント

select distinct 
        <select_list>
from
    <left_table><join_type>
join <right_table> on <join_condition>
where
    <where_condition>
group by
    <group_by_list>
having
    <having_condition>
order by
    <order_by_condition>
limit <limit number>

3.2 SQLの実行順序
 

1、from <left_table><join_type>
2、on <join_condition>
3、<join_type> join <right_table>
4、where <where_condition>
5、group by <group_by_list>
6、having <having_condition>
7、select
8、distinct <select_list>
9、order by <order_by_condition>
10、limit <limit_number>

4. 人間の言葉で話す---各分野の事例分析の意味を説明する

4.1、ID

選択クエリのデジタル シーケンス番号は、クエリ内の選択句または複数テーブル結合クエリを実行するときにテーブルが操作される順序を示します; ( 1 ) ID が同じで、実行順序は上から一番下まで。

3 つのテーブル t1、t2、および t3 から t2 テーブル全体をクエリします。クエリ条件は次のとおりです: t1.id=t2.id、t1.id=t3.id、および t1 の他のフィールドは空です。オプティマイザは条件を処理します同じ
where 内では、デフォルトでは右から左に読み取るため、
3 つのテーブルの実行順序は t1 -> t3 -> t2 になります。

(2) ID が異なりますので、ID が大きいほど実行優先度が高くなります。

サブクエリの場合は、再帰の考え方と同様に、ID のシーケンス番号がインクリメントされ、その中のサブクエリが最初に実行され、() 内のステートメントが優先されます。

t2 テーブルからすべての t2 テーブルをクエリします。クエリ条件は id で、クエリ条件は 3 レベルのネストです:
テーブル t1 から ID をクエリします - id はテーブル t3 からクエリされた t3 テーブルの ID です - その他t3 テーブルのフィールドは空です。
再帰的思考を使用すると、テーブルの実行順序 (t3 -> t1 -> t2) を簡単に判断できます。

(3) 同じIDと異なるIDが同時に存在する場合があり、IDが異なるものやIDが大きいものが先に実行され、同じIDのものは上から順に実行されます。

ここで概念を導入する必要があります、派生仮想テーブル クエリ (派生):
元のテーブルから部分的な情報がインターセプトされ、その結果のセットで新しいテーブルを形成できます。このテーブルは実際には存在せず、仮想テーブルと呼ばれます。クエリの種類 派生仮想テーブルクエリと呼ばれます。

(テーブル t3 からテーブル t3 の ID をクエリし、クエリ条件は他のフィールドが空であること) 括弧内のテーブル t3 のクエリ条件の結果セットを仮想テーブル s1 として使用し、仮想テーブル s1 とテーブル t2 からテーブル t2 をクエリします。テーブル t2
。いずれも、クエリ条件は s1.id=t2.id であるため、クエリ シーケンスは次のようになります
: t3 ->derived2 -> t2
ID=2;

4.2、タイプの選択 

クエリ タイプには、次の合計 6 つのテーブル クエリ タイプがあります。

· (1) SIMPLE
単純なクエリ。クエリにはサブクエリとユニオン (結合クエリ) が含まれません。

· (2)
PRIMARY クエリにサブクエリが含まれる場合、最も外側のクエリは PRIMARY としてマークされます。

・(3)
select または where リスト内の SUBQUERY のサブクエリ

· (4) DERIVED の
典型的な構文: from (サブクエリ) s1、
from リストに含まれるサブクエリは DERIVED (派生) としてマークされ、このサブクエリの実行後の結果セットは仮想テーブル s1 に配置されます。

· (5) UNION
Union の後に 2 番目の select が出現する場合、それは Union マルチテーブル クエリとしてマークされます;
Union が from 句のクエリ、つまり select 属性 from (サブクエリ 1 Union サブクエリ 2) s1 に含まれている場合、 this 外側の選択範囲は DERIVED としてマークされます。


・(6) UNIONテーブルから結果を取得する UNION RESULT SELECT

4.3、表

 ID に対応するテーブルを参照し、テーブルの実行順序は ID によって決まります。また、
この行のデータがどのテーブルに関係するかも参照します。

4.4、タイプ

 クエリを表示する場合、どのクエリ タイプが使用されますか? 日常業務でよく遭遇するのは次の 7 タイプです。パフォーマンスは最高から最悪の順です:
system > const > eq_ref > ref > range > index > ALL が
一般的にクエリを保証する必要があります。 type レベルが範囲 (できれば ref) に達するため、ALL の使用は避けてください。

· (1) システム
クエリとは、テーブル内にデータが 1 行しかないことを意味します。これは const の特殊なケースであり、通常は表示されません。情報が 1 行しかないため、ビッグデータとは呼ばれません。あまり重要ではありません。

・(2)定数

定数クエリとは、インデックス Index 1 回で検索できることを意味し、主キー = 定数、一意 = 定数などのインデックスを比較するために使用されます。
主キーが where リストに配置されている場合、MySQL には自動型変換機能があります。クエリを定数として自動的に変換します。

ここに画像の説明を挿入します

 d1 は仮想テーブルであり、括弧が優先されます。テーブル t1 が最初に実行されます。id = 1 は定数クエリ const です。
仮想テーブル d1 には 1 行のデータしかないため、クエリ タイプはシステム クエリ システムです。

・(3)eq_ref

一意のインデックス スキャン: 各インデックス キーについて、テーブル内のデータは 1 行のみであり、主キーでは一般的です。

ここに画像の説明を挿入します

 where の後に括弧はありません。MySQL オプティマイザは左から右に実行されます。したがって、テーブル t2 が最初に実行され、タイプは ALL です。完全なテーブル クエリは 639 行の情報に対応します。次にテーブル t1 がクエリされます。タイプは eq_ref
、テーブル 1 の ID は 1 行の情報にのみ対応します。 、一意のインデックス スキャン。

· (4) ref
非一意インデックス スキャン。インデックス キーごとに、テーブル内に複数のデータ行が存在する可能性があります。

 クエリ テーブル t1 には、col1 という 7 つの一意のフィールドがあり、残りはすべて重複しています。
クエリ条件 Col1='ac' を満たすレコードが 284 行あるため、これは ref 非一意インデックス スキャンです。

 · (5) 範囲
クエリ、where の後のリストは between、<、>、in などのクエリです。

ここに画像の説明を挿入します

 と type の間のキーワードは範囲検索です。

ここに画像の説明を挿入します

キーワード in と type は範囲検索です;
★ キーワード like も範囲検索ですので後ほど書きます。

· (6) インデックスの
全インデックス スキャン、FULL INDEX SCAN はインデックス ツリーのみを走査し、通常は ALL よりも高速です (
インデックスと ALL は両方とも完全なテーブル クエリですが、インデックスはインデックスから読み取り、ALL は完全なテーブルから読み取ります)。

· (7) ALL
フル テーブル スキャン、FULL TABLE SCAN は、テーブル全体を走査して一致する行を見つけます。これは最も遅いため、使用は避けてください。

4.5. possible_keys

 クエリされたフィールドにインデックスがある場合は、1 つ以上のインデックスがリストされますが、それらはクエリ中に実際に使用されない場合があります。

4.6.

 実際に使用されるインデックス。NULL の場合、インデックスは使用されません。考えられる一般的な理由:
· (1) インデックスが作成されていない
· (2) SQL ステートメントが正しく書かれておらず、インデックスが無効である。
· (3) possible_key の場合も NULL です。インデックスが作成されていないことを意味します。

4.7. key_len

key_len を通じてインデックス フィールドの数を確認できます。74 は 1 を指し、78 は 2 を指し、140 は 3 を指します。

4.8. 参照

どのフィールドがインデックス付けされているかを表示します。これは const 定数にすることができます
。 ps: 型の ref は、非一意のインデックス スキャンを参照します。インデックス フィールドの場合、複数の重複値が存在する可能性があります。

ここに画像の説明を挿入します

テーブル t1 とテーブル t2 からすべてをクエリします、クエリ条件: t1.col1=t2.col1、t1.col2='ac';
同じ where リストで、オプティマイザは右から左に実行され、インデックスには 2 つのフィールドがあります
。フィールド値 'ac' (const 定数);
次に、共有データベースのテーブル t2 のフィールドcol1 (shared.t2.col1) を実行します。

4.9.
行インデックスをクエリするときは、必要なレコードを読み取るために必要な行数を大まかに見積もります。

4.10. 余分な

 付加情報には、以下の3種類があります:
・(1) filesort使用時は、
作成・使用準備したインデクスが使用されておらず、ファイルソートが行われていることを示しており、
SQL文の記述に問題がある可能性があります。 ; 以前に確立されたインデックスインデックスと競合します。

· (2) 一時的な使用は
、中間結果を保存するために一時テーブルを使用します。これは、確立されたインデックスが完全には使用されていないことを示します。
これは、並べ替え順序による並べ替えやグループ クエリのグループ化によくあります。

・(3)
インデックス使用選択操作ではカバリングインデックスが使用されており、SQL実行効率が良いことがわかります。
カバーインデックス:
例: 最初にインデックスフィールド a_フィールド b を作成し、
次にフィールド a=...、フィールド b=... であるテーブルのフィールド a、フィールド b を選択します。
つまり、最初に特定のフィールド Index を使用してインデックスを作成します。次に、インデックス内のフィールドをクエリします。where リストはインデックス フィールドの値です。つまり、インデックス フィールドの値が XXX の場合、フィールドをクエリします。これが最も効率的な選択方法です。
··· where が同時に出現する場合は、インデックスキー値の検索にインデックスが使用されていることを示します; · ·
where が同時に出現しない場合は、インデックスが使用されていないことを示しますインデックス キー値の検索を実行するために使用されますが、データの読み取りにのみ使用されます。
 

おすすめ

転載: blog.csdn.net/u010445301/article/details/126220108