MySQLのEXPLAIN

EXPLAINはSELECTステートメントの実行プランに関する情報を提供します。つまりSQLの実行計画、「mysqlが作成したクエリをどのように判断して実行したのか」というものが
見れるようなものです。(データへのアクセス方法がわかるものです。)
これにより現在どのようにクエリが実行されているかということを知ることができ、これを知ることでクエリの最適化(※)へとつなげることができる。
(※)クエリを最適化するということは、
・書き換える前と後でクエリの実行結果が同じになる
・EXPLAINがよりよい実行計画を表示する
ということ

使い方

SELECT文の先頭に「EXPLAIN」をつけて実行する
例)

出力結果)

各フィールドの情報について

id

SELECT識別子。クエリー内のSELECTの連番です。

select_type

クエリの種類を表すもの。クエリの種類とはJOIN、サブクエリ、UNIONおよびそれらの組み合わせのことで、select_typeの内容もその組み合わせから導き出されたものである。

JOINの場合

MySQLが実行できるJOINの種類は「Nested Look Join(NLJ)」の一種類しかない。
テーブルを一つずつ順に処理していく方式のこと。クエリがJOINだけから構成される場合、select_typeは「SIMPLE」と表示される。SIMPLEではidが全て同じ値になる。EXPLAINの出力の順序がどのテーブルから処理するかということを反映している。

サブクエリの場合

次の5種類のうちいずれかが表示される。

  • PRIMARY・・・外部クエリを示す。
  • SUBQUERY・・・相関関係のないサブクエリ。
  • DEPENDENT SUBQUERY・・・相関関係のあるサブクエリ。
  • UNCACHEABLE SUBQUERY・・・実行する度に結果が変わる可能性のあるサブクエリ。
  • DERIVED・・・FROM句で用いられているサブクエリ。
UNIONの場合

クエリにUNIONが含まれる場合、次の5種類のいずれかがselect_typeに表示される。

  • PRIMARY・・・UNIONにおいて最初にフェッチされるテーブル
  • UNION・・・2番目以降にフェッチされるテーブル
  • UNION RESULT・・・UNIONの実行結果
  • DEPENDENT UNION・・・DEPENDENT SUBQUERYがUNIONになっている場合
  • UNCACHEABLE UNION・・・UNCACHEABLE SUBQUERYがUNIONになっている場合

table

出力の行で参照しているテーブルの名前。

table

このフィールドはレコードアクセスタイプとも呼ばれ、対象のテーブルに対してどのような方法でアクセスするかを示す。致命的なクエリはこのフィールドを見れば一目で分かるのでとても重要なフィールドである。よく見かけるものは次の通り。

  • const・・・PRIMARY KEYまたはUNIQUEインデックスのルックアップによるアクセス。最速。
  • eq_ref・・・JOINにおいてPRIARY KEYまたはUNIQUE KEYが利用される時のアクセスタイプ。constと似ているがJOINで用いられるところが違う。
  • ref・・・ユニーク(PRIMARY or UNIQUE)でないインデックスを使って等価検索(WHERE key = value)を行った時に使われるアクセスタイプ。
  • range・・・インデックスを用いた範囲検索。
  • index・・・フルインデックススキャン。インデックス全体をスキャンする必要があるのでとても遅い。
  • ALL・・・フルテーブルスキャン。インデックスがまったく利用されていないことを示す。OLTP系の処理では改善必須。

※indexまたはALLを見かけたらすかさずクエリをチューニングしよう。

possible_keys

オプティマイザがテーブルのアクセスに利用可能なインデックスの候補として挙げたキーの一覧。

key

オプティマイザによって選択されたキー。

key_len

選択されたキーの長さ。インデックスの走査は、キー長が短い方が高速である。

ref

検索条件で、keyと比較されている値やカラムの種類。定数が指定されている場合はconstと表示される。JOINが実行されている時には、結合する相手側のテーブルで検索条件として利用されているカラムが表示される。

rows

rows カラムは、MySQL がクエリーを実行するために調査する必要があると考える行数を示します。
※InnoDB テーブルの場合、これは推定値であり、常に正確ではないことがあります。

EXTRA

MySQL がクエリーを解決する方法に関する追加情報が含まれます。

  • Using where・・・頻繁に出力される追加情報であまり気にする必要はない
  • Using index・・・クエリがインデックスだけを用いて解決できることを示す。カバリングインデックスを利用している場合などに表示される。
  • Using filesort・・・ソートを行っている。適切なインデックスを張ることで改善されるかもしれないことを表す。

※参照:
http://qiita.com/Tsuji_Taku50/items/43eb2a41915d03173773
https://dev.mysql.com/doc/refman/5.6/ja/explain-output.html#explain-output-column-table

WordPress Webサイトの表示を行う場合の順序

  1. ブートストラップ(wp-load.php)をロードし、WordPressを起動。
     → WordPressの起動と初期化
  2. wp関数はHTTPリクエストのクエリ文字列をWordPressクエリに変換し、それをデータベースのSQLクエリに変換しページ表示に必要なデータを取得
     → WordPressクエリの実行
  3. テンプレートローダー(template-loader.php)がテーマの中から適用すべきテンプレートファイルを決定する
     → テーマの適用

※wp-blog-header.phpの構造

WordPressコア

WordPressコアはWordPressの基本機能を提供するWordPressの構成要素です。
ファイル上はwp-contentディレクトリ(テーマ、プラグイン、アップロードファイル)とwp-config.phpファイル(設定ファイル)以外は全てWordPressコアです。

関数ファイルやクラスファイルなどの共通ライブラリとしてのPHPファイルはwp-includesディレクトリにまとめられています。
WordPress実行時には、Webサイトの表示であっても管理画面の表示であっても、その他であってもwp-includesディレクトリの多くのファイルが共通ライブラリとしてロードされます。

(1)Webサイト表示の場合
ルートディレクトリ直下のindex.phpがフロントコントローラーとして機能し、WordPressコア(WordPressの実行)がスタートします。

(2)管理画面の場合
wp-adminディレクトリ内の各PHPファイルがページコントローラーとして機能し、WordPressコア(WordPressの実行)がスタートします。
=機能ごとに最初にアクセスされ、実行されるファイルが異なる。
例)wp-admin/index.php・・・ダッシュボードページのページコントローラー
  wp-admin/upload.php・・・メディアライブラリページのページコントローラー

管理画面内で共通して利用される関数ファイルやクラスファイルなどのPHPファイルはwp-admin/includesディレクトリ内にまとめられています。実行領域にかかわらずロードされるwp-includesディレクトリ内の共通ファイブラリをロードした後に追加してロードされます。

※wp-adminディレクトリ内のPHPファイルのうちwp-admin/admin-ajax.phpのみはログインの有無を問わず実行される

(3)その他の領域
管理画面同様、WordPressコアはページコントローラー方式で起動します。

WordPressの構成要素

WordPressは以下の6つの構成要素によって成り立っています。

  1. WordPressコア
  2. プラグイン
  3. データベース
  4. 設定ファイル(wp-config.php)
  5. アップロードデータ
  6. テーマ

このうち、データベースを除く5つの構成要素の実態は通常のファイルやディレクトリです。

WordPressの実行領域

WordPressの実行領域

主としてWordPressが最初にHTTPリクエストを受け取る領域。
ブラウザからアクセスされる領域で、多くの場合はHTTPリクエスト。
以下の3つの領域に分けられる

  1. Webサイトの表示
  2. 管理画面
  3. その他

1.Webサイトの表示

Webサイトのトップページや個別ページなどのWebサイトそのものの領域。
WordPressはフロントコントローラー方式で起動。
※index.phpの実行=WordPressの実行

2.管理画面

記事を投稿したりWordPressを設定したりする管理領域。
WordPressはページコントローラー方式で起動。
※wp-adminディレクトリ内に個別に設定されている各機能ごとのPHPファイルの実行=WordPressの実行

3.その他

Webサイトの表示と管理画面以外の領域。(ログインページやAjaxページなど)
ページコントローラー方式で起動。

HTTPリクエストとHTTPレスポンス

HTTPリクエスト

ブラウザからwebサーバーへの要求メッセージ

response

1.リクエストライン・・・1行目
2.HTTPリクエストヘッダ・・・2行目から次の空行まで
3.HTTPリクエストボディ・・・その次以降
の3パートからなる。

※リクエストラインに記載されるリクエストメソッドがGETの場合はリクエストボディはなし。
 (POSTメソッドの場合ボディ部にPOSTデータが格納される)

HTTPレスポンス

Webサーバーからブラウザへの応答メッセージ

request

1.ステータスライン・・・1行目
2.HTTPレスポンスヘッダ・・・2行目から次の空行まで
3.HTTPレスポンスボディ・・・その次以降
の3パートからなる。

SHORTINIT

説明

WordPressの初期化処理を短縮するかどうかを示す定数。標準ではfalse(短縮しない)となる。
※trueに設定するとWordPressの起動プロセスを短縮させる。

例(wp-include/defualt-contents.php)

上記の例でSHORTINITをtrueに設定すると、wp-config.phpからロードされるwp-setting.phpの中盤で、データベースに接続したあとで、処理を停止して制御をコントローラーに戻します。

注意事項

主にバッチ処理などでデータベースを直接コントロールするための処理などの場合に用いる。利点は初期化処理を簡略化し、初期化処理を高速化することです。
この定数はwp-config.phpに記述することもの可能ですが、通常のWebサイトとして動作しているWordPressの場合には、表示が行われなくなりますので注意が必要です。