MySQLのEXPLAINの実行例と解析方法についてまとめました。
※目次をクリックすると目次の下部にコンテンツが表示されます。
- 1.プライマリキーの単純検索
- 2.プライマリキーの範囲検索
- 3.キー未設定カラムの範囲検索
- 4.複数のカラムを範囲検索
- 5.likeを使って前方、後方、部分一致
- 6.REGEXP句で正規表現を使って検索
- 7.”Using index”について
- 8.where句ではインデックスキーに式や関数を指定しない
mysql> EXPLAIN SELECT id,name from example where id = "13_88248460" \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: const possible_keys: PRIMARY key: PRIMARY key_len: 38 ref: const rows: 1 Extra: NULL 1 row in set (0.00 sec)
2)各項目の説明
・id
クエリのID(テーブルのIDではないので注意)
・select_type
クエリの種類を表す。
SIMPLE:単純な SELECT (UNION やサブクエリーを使用しない)。
・table
対象のテーブル
・type
レコードアクセスタイプ。どのようにテーブルにアクセスされるかを示す。
const:テーブルに、一致するレコードが最大で 1 つあり、クエリーの開始時に読み取られる。レコードが 1 つしかないため、このレコードのカラムの値はオプティマイザによって定数と見なされる。const テーブルは、1 回しか読み取られないため、非常に高速。const は PRIMARY KEY/UNIQUE キーを定数と比較する場合に使用される。
・possible_keys
利用可能なキー。
・key
MySQL が実際に使用を決定したキー (インデックス)。
・key_len
選択されたキーの長さ(バイト)
・rows
行数の概算見積もり。
・Extra
オプティマイザヒント。
mysql> EXPLAIN SELECT id FROM example WHERE id BETWEEN "13_000000000" AND "13_999999999" \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: range possible_keys: PRIMARY key: PRIMARY key_len: 38 ref: NULL rows: 5737 Extra: Using where; Using index
2)単純検索の結果との相違
①typeが”const”から”range”に変りました。
※type
レコードアクセスタイプ。どのようにテーブルにアクセスされるかを示す。
●const
・一致するレコードが最大で1つあり、クエリーの開始時に読み取られる。
・レコードが1つしかないため、このレコードのカラムの値はオプティマイザによって定数と見なされる。
・テーブルは1回しか読み取られないため、非常に高速。
・PRIMARY KEY/UNIQUEキーを定数と比較する場合に使用される。
●range
・インデックスを使用して、一定の範囲にあるレコードのみが取り出される。
・keyカラムに使用されるインデックスが示される。
・key_len_には使用される最長のインデックス部分が記載される。
・この型ではrefカラムがNULLになる。
・rangeは、=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN、IN()を使用してキーカラムを定数と比較する場合に使用できる。
②Extra(MySQLでどのようにクエリーが解決されるかに関する追加情報)がNULLだったのが”Using where; Using index”と記述されています。
●Using index
・インデックスツリーの情報のみを使用してカラム情報がテーブルから取り出され、実際の行を読み取るその後の検索を実行する必要がないことを示す。
・この方針は、クエリーで単一のインデックスの構成部分であるカラムのみが使用される場合に使用できる。
●Using where
・次のテーブルとの一致が調べられるレコードまたはクライアントに送信されるレコードの限定にWHERE節が使用されることを示す。
・この情報がなく、Extraの値がUsing whereではなく、テーブルの型がALLまたはindexである場合はクエリーが正常に実行されないことがある(テーブルのすべてのレコードの取得や検査を意図していない場合)。
mysql> EXPLAIN SELECT count(*) FROM example WHERE build <= 2010 \G
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 11474 Extra: Using where
カラムにキーが設定されていないため、typeがALLになっています。フルテーブルスキャンが実行されています。
●キー追加
mysql> ALTER TABLE example ADD INDEX (build);
2)キー設定後のEXPLAIN実行例(プライマリキー以外の範囲検索)
mysql> EXPLAIN SELECT count(*) FROM example WHERE build <= 2010 \G
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: range possible_keys: build key: build key_len: 5 ref: NULL rows: 5737 Extra: Using where; Using index
typeがrangeに変ってインデックスが使用されています。
mysql> EXPLAIN SELECT count(*) FROM example WHERE build <= 2010 AND size < 15 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: range possible_keys: build,size key: size key_len: 5 ref: NULL rows: 122 Extra: Using index condition; Using where 1 row in set (0.03 sec) mysql> EXPLAIN SELECT count(*) FROM example WHERE build <= 1990 AND size < 30 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: range possible_keys: build,size key: build key_len: 5 ref: NULL rows: 1842 Extra: Using index condition; Using where
buildとsizeの二つのカラムにインデックスが指定されていてキーとして使用可能となっています。実際にどちらのキーを使用するかは、指定した検索条件を考慮し、選択してくれるようです。
○前方一致 mysql> EXPLAIN SELECT count(*) FROM b_example1 WHERE address like '東京都千代田区%' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: b_example1 type: range possible_keys: address key: address key_len: 243 ref: NULL rows: 64 Extra: Using where; Using index ○部分一致 mysql> EXPLAIN SELECT count(*) FROM b_example1 WHERE address like '%中央%' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: b_example1 type: index possible_keys: NULL key: address key_len: 243 ref: NULL rows: 11474 Extra: Using where; Using index ○後方一致 mysql> EXPLAIN SELECT count(*) FROM b_example1 WHERE address like '%中央町2丁目' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: b_example1 type: index possible_keys: NULL key: address key_len: 243 ref: NULL rows: 11474 Extra: Using where; Using index
①前方一致
type: rangeとなっていて、インデックスを使用して、一定の範囲にあるレコードのみが取り出されています。
②部分一致、後方一致
type: index、possible_keys: NULLとなっていてインデックスが使用されていないことが分かります。
※typeのindexは下記意味になります。
インデックスツリーのみがスキャンされる点を除いてALL(フルスキャン)と同じである。一般にインデックスファイルはデータファイルより小さいため、通常は ALL より高速である。
mysql> EXPLAIN SELECT address FROM example WHERE address REGEXP '.*月島(1|1|2|2)丁目' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: index possible_keys: NULL key: address key_len: 243 ref: NULL rows: 11474 Extra: Using where; Using index mysql> EXPLAIN SELECT count(id) FROM example WHERE address REGEXP '^東京都(千代田区|港区).*' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: example type: index possible_keys: NULL key: address key_len: 243 ref: NULL rows: 11474 Extra: Using where; Using index
先頭の文字列、後方の文字列の如何に関わらずtype: index、possible_keys: NULLとなっていてインデックスが使用されていないことが分かります。
※typeのindexは下記意味になります。
インデックスツリーのみがスキャンされる点を除いてALL(フルスキャン)と同じである。一般にインデックスファイルはデータファイルより小さいため、通常は ALL より高速である。
クエリーでインデックスの構成部分であるカラムのみが使用される場合に表示される。
例1)Using indexが表示される例
where句でインデックスを使って条件を指定し、インデックスで指定したカラムのみ表示。
mysql> explain select id_eki,build from sample where id_eki = '2164020' and build = '2010' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sample type: index_merge possible_keys: build,id_eki key: id_eki,build key_len: 33,5 ref: NULL rows: 3 Extra: Using intersect(id_eki,build); Using where; Using index 1 row in set (0.00 sec)
例2)インデックスが使用されていない場合
カラムにキー項目を指定していても前方後方一致などでインデックスが使用されない条件を指定するとUsing indexとはならない。
mysql> explain select id_eki,build from sample where id_eki like '%210%' and build = '2010' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sample type: ref possible_keys: build key: build key_len: 5 ref: const rows: 201 Extra: Using where 1 row in set (0.00 sec)
例3)すべてのカラムを表示する場合
インデックスが使用されていてもインデックス以外のカラムを表示しているのでUsing indexとならない。
mysql> explain select * from sample where id_eki = '2164020' and build = '2010' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sample type: index_merge possible_keys: build,id_eki key: id_eki,build key_len: 33,5 ref: NULL rows: 3 Extra: Using intersect(id_eki,build); Using where 1 row in set (0.00 sec)
・下記のような単純な式を使ったクエリーでも問題となってしまうので注意する。
SELECT id FROM member WHERE id + 1 = 5;
・関数を使用した例
select id, created from Sample where to_days(current_date) - to_days(created) <= 7;
-
インストール、基本設定、文字コード、仕組み
- MySQLのインストール
- CentOS6でMySQL5.1からMySQL5.7へアップデートする手順、注意点
- CentOS6.10でMySQL5.7からMySQL8へアップデートする手順、注意点
- MySQLサーバーの起動スクリプト(v5.1)
- MySQLのファイルシステムとストレージエンジンの概要
- MySQLのデータ型の概要
- MySQLのサーバー、データベース、テーブル、カラムの文字コード設定とクライアントからのサーバー接続時の文字コード設定
- MySQLの”LOAD DATA INFILE”などでCSVファイル入出力時の文字コード、権限などの注意点
- セキュリティを考慮し、MySQLの匿名ユーザーにパスワードを設定、または削除
- CentOS6にphpMyAdminを導入
- MySQLのbツリーインデックスの概要とマルチカラムインデックス
- MySQLのプレフィックスインデックス、FULLTEXTインデックスの概要
- MySQLのEXPLAINの実行例
- MySQLのインデックス結合の概要
- MySQLのSelect文でインデックスのカラムのみ取得する場合のメリット
- MySQLのORDER BY句でインデックスを使用
- MySQLのPACK_KEYSオプション
- MySQLのインデックス統計更新の概要
- MySQL初期設定確認
- mysqladminコマンドでMySQLサーバーの状態確認
- mysqlshowコマンドで簡単にデータベース、テーブル定義の確認
- awkを使ってmysqlshowの必要な列のみ表示
- MySQLのスロークエリログの概要と表示方法
- show profileでクエリーの内部処理時間を調査
- MySQL Benchmark Suiteによるパフォーマンス測定
- MySQLの診断、監視に利用できる外部ツール
- WordPressデータベースのバックアップとリストア
- Bashスクリプトでmysqldumpバックアップと世代管理
- MySQLの壊れたテーブルのチェック、修復方法
- MySQLのインデックス統計更新の概要
- MySQLのフラグメンテーションの概要と改善方法
- MySQLのスレッド、コネクションに関する設定値、チューニング
- MySQLのセッション単位に設定するバッファーサイズ
- MySQLのクエリキャッシュの設定値、パフォーマンス
- MySQLのテーブルオープン、クローズとテーブルキャッシュのチューニング
- MyISAMキーキャッシュの概要とチューニング
- MySQLのソートに関する設定値とステータス
- MySQL innoDBの性能関連の設定値とステータス確認
- MySQL MyISAMの性能関連の設定値とステータス確認
インデックス
状態確認、調査
バックアップ、リストア、メンテナンス
パフォーマンス、チューニング