DBチューニング(3)
データの検索がどのように行われるかを見てみます。
explain extendedはMySQL 5.1.12からの新機能です。
explain extended select * from table01 where id=777; +----+-------------+---------+------+---------------+------+---------+------+---------+----------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+----------+-------------+ | 1 | SIMPLE | table01 | ALL | NULL | NULL | NULL | NULL | 1000059 | 100.00 | Using where | +----+-------------+---------+------+---------------+------+---------+------+---------+----------+-------------+ 1 row in set, 1 warning (0.02 sec) mysql> explain extended select * from table02 where id=777; +----+-------------+---------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | table02 | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | | +----+-------------+---------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.04 sec)
rowsの数値が全く異なります。これはtable02の設計ではid=777はレコードに一つしか存在せず、
rowsカラムは、クエリの実行に際して調べる必要があると MySQL によって判定されたレコードの数を示しています。
実行計画について
''explain''の使用方法を説明します。
前述したexplainの実行結果にいくつかのフィールドが表示されています。このフィールドの見方を覚えるとSQLにもっと詳しくなれます。
idとselect_type
前述の例ではidが1となっていますがこれはJOIN、サブクエリ、ユニオンが絡むと複数出現します。
select_typeも同様です。
ひとまずまだ導入部分なのでこの説明はここまでにとどめます。
table
対象となるテーブルです。
type
table01は''ALL''です。このクエリを発行した場合、フルテーブルスキャンを行うことを意味します。テーブル定義にはインデックスがまったく利用されていないため、テーブル全体をチェックする必要があります。
table02は''const''です。このクエリを発行した場合、テーブルに一致する行が一行のみ(Primary KeyもしくはUnique)なので検索結果は高速です。
以下が主な値とその意味です。
const | PRIMARY KEYまたはUNIQUEインデックスによるアクセスなので最速 | ||||
eq_ref | constと似ているがJOINで用いられるところが違う | ||||
ref | ユニークでないインデックスを使って等価検索 | ||||
range | インデックスを用いた範囲検索 | ||||
index | フルインデックススキャン。インデックス全体をスキャンする必要があるのでとても遅い。 | ||||
ALL | フルテーブルスキャン。インデックスがまったく利用されていないことを示す。 |
possible_keys
インデックスの候補。検索時に使うとよいと思われるキーです。この判断はオプティマイザが行います。
key
オプティマイザが指定したキーです。
key_len
table01はnullですが、table02は長さが4となっていますが、これはプライマリであるidが''int型''であり、''int型''で必要な記憶容量が4バイトなのでこの結果が表示されています。
この値が小さいほうが検索は高速になります。
ref
refカラムは、テーブルからレコードを選択する際に keyとともに使用されるカラムまたは定数を示す。
rows
rowsカラムは、クエリの実行に際して調べる必要があると MySQL によって判定されたレコードの数を示す。
filtered
filteredカラムはテーブルの状態によってフィルターされるテーブル行のパーセンテージ(予想)を表示します。つまり、rowsは検査された行の予想数を表示し、rows × filtered / 100は前のテーブルと結合する行の数を表示します。