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は前のテーブルと結合する行の数を表示します。

Extra

このカラムには、MySQL でどのようにクエリが解決されるかに関する追加情報が記載されます。

explainを使うと、MySQLがどのようにデータを取得しようとするのか、その計画を知る事ができます。もしフルインデックススキャンやフルテーブルスキャンが行われようとしていればそのクエリを改めたほうがよいでしょう。

この辺で力つきます…