SQLをどのように最適化するか本当に分かりますか?


概要
Explaninを使って、すぐにSQLを調整することができません。いくつかの調整提案もできませんが、MySQL最適化器がどのようにSQL文を実行しているかを知ることができます。
Explinを通じて、以下の結果を分析できます。
  • テーブルの読み出し順序
  • データ読出し動作の動作タイプ
  • どのインデックスが
  • を使用できますか?
  • どのインデックスが実際に使われていますか?
  • テーブル間の参照
  • 各テーブルの何行が最適化器によって照会されますか?
    Explinコマンドの使い方はとても簡単です。select文の前にExplinをつければいいです。例えば、
    
    explain select * from user;
    その結果は主に以下のフィールドが含まれています。
    id、select_type、table、partitions、type、possible_keys、key、ref、rows、filtered、extra
    次に、各フィールドの意味を見てみましょう。
    id検索シーケンス番号
    テーブルの読み込み順序

    接続クエリの各テーブルのロード順序は同じですので、すべて1です。

    サブクエリを含む場合は、先にサブクエリを実行しますので、ユーザーテーブルのID値が一番大きいです。
    select_.タイプを検索
    よく使う値は以下の通りです
  • SIMPPLE:簡単なselectクエリは、サブクエリとインデックス
  • を含んでいません。
  • PRIMARY:クエリーにサブクエリが含まれている場合、最外層クエリはPRIMARY
  • として記載されています。
  • SUBQUEY:SELECTまたはWHEREリストにサブクエリ
  • が含まれています。
  • DERIVED:FROMリストに含まれるサブクエリはDERIVEDとしてマークされ、MySQLはこれらのサブクエリを再帰的に実行し、結果を仮テーブルに置く
  • UNION:2番目のSELECTがインデックスの後に表示されるとUNIONとしてマークされます。インデックスがFROMサブクエリに含まれている場合、外層SELECTはDERIVED
  • と表記されます。
  • ユニオンRESULT:インデックステーブルから結果を取得したクエリー
  • テーブルクエリに関する表または派生表
    タイプを検索
    typeフィールドを通じて、今回のクエリーは全表スキャンかインデックススキャンかなど、typeでよく使われる値があります。
    system:表は一つのデータしかありません。
    const:プライマリキーまたは一意索引の等値クエリースキャンに対して、簡単に読み取ればデータが得られます。例えば、以下のプライマリキーインデックスのクエリーなどです。

    eq_ref:一意のインデックススキャンは、各インデックスキーに対して、テーブル内のレコードが一つだけマッチします。主キーまたは一意の索引スキャンによく使用されます。
    ref:一意でない索引スキャンは、個々の値にマッチするすべての行を返します。
    レンジング:インデックス範囲クエリを使用することを表します。例えば、=、<>、>、>=、<、=、IS、NULL、<=>、BETWEEN、INなどです。
    index:検索するデータはインデックスツリーで直接取得できます。スキャンデータは不要です。例えば、

    ALL:全表スキャンを表しています。このタイプのクエリは一番性能が悪いクエリです。
    タイプの性能比較
    通常、タイプ別の性能関係は以下の通りです。
    ALL<index<range<ref>eq_ref
    possiblekeysクエリーで使用できる索引。
    possiblekeysはMySQLが照会時に使用できるインデックスを示しています。必ずしも使用するものではないので、実際の使用はkeyフィールドで決定されます。
    keyクエリーで使用する索引
    このフィールドはMySQLが現在のクエリーで本当に使用している索引です。
    key_lenインデックスを使用するバイト数
    このフィールドは、結合インデックスが完全に使用されているかどうかを評価することができます。または、一番左端のフィールドのみが使用されます。
    ローソンMySQLは、検索結果セットにスキャンして読み込むデータの行数を推定する。
    Extraの追加情報
    よく見られるのは以下のような内容があります。
  • Using filesort:MySQLは追加的なソート操作が必要で、インデックス順でソート効果に達することができません。一般的にUsing filesortがあります。最適化除去を提案しています。このような問い合わせはCPU資源の消費が大きいです。
  • Using index:インデックスツリーで検索するために必要なデータを検索することができるという意味で、スキャンテーブルのデータファイルを使わずに、性能が良いと説明することが多いです。
  • Using temporary:クエリは一時テーブルを使用しています。一般的に並べ替え、グループと複数のテーブルjinの場合に発生します。クエリの効率が高くないので、最適化を提案します。
  • Using where:whereフィルタ
  • を使用していることを示します。
  • Using join buffer:接続キャッシュを使用していることを示しています。例えば、クエリの際に、複数のテーブルjinの回数が非常に多い場合、設定ファイルのバッファのjoin bufferを
  • に大きくします。
  • impossible where:where子文の値は常にfalseであり、任意のタプル
  • を取得するためには使用できません。
  • select tables optimized away:GROPY子文がない場合、インデックスに基づいてMIN/MAXを最適化したり、MyISAM格納エンジンに対してCOUNT(*)を最適化したりする操作は、実行段階を待たずに計算を行う必要がありません。クエリー実行計画の生成段階は、優化
  • を完了します。
  • distinct:distinct動作を最適化し、第1マッチのタプルを見つけたら、同じ値を探す動作を停止する。
    締め括りをつける
    以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考学習価値を持ってほしいです。ありがとうございます。