MySQLの遅いSQLを改善する方法|初心者でもわかるインデックス最適化とチューニング完全解説
生徒
「MySQLを使っていると、検索がすごく遅くなることがあるんですが、どうしてなんですか?」
先生
「データの探し方に原因があることが多いですね。特にインデックスという仕組みが関係していることが多いです。」
生徒
「インデックスって聞いたことはありますけど、正直よくわかりません……。」
先生
「本の後ろにある索引と同じ仕組みです。ページを最初から全部読まなくても、すぐ目的の場所が見つかりますよね。」
生徒
「じゃあ、その索引がないと遅くなるんですか?」
先生
「その通りです。今日はMySQLで遅いSQLがなぜ発生するのかを、インデックスの視点から丁寧に説明します。」
1. MySQLとSQLの基本をやさしく理解しよう
MySQLは、たくさんのデータを整理して保存できる「データベース管理システム」です。紙の名簿をパソコンの中に入れたものだと考えるとイメージしやすいです。
SQLとは、その名簿に対して「この人を探して」「この情報を表示して」とお願いするための言葉です。MySQLでは、このSQLを使ってデータを検索します。
SQLが遅いというのは、「探し方が下手で、名簿を最初から最後まで全部見ている状態」になっていることが多いです。
2. インデックスとは何か?初心者向けのたとえ話
インデックスとは、データを早く探すための「目次」や「索引」のようなものです。電話帳で名前を探すとき、最初のページから全部読まないですよね。
MySQLのインデックスも同じで、特定の列(カラム)に目印を付けて、すぐ場所が分かるようにします。
インデックスがない場合、MySQLはすべての行を一つずつ確認します。これをフルスキャンと言い、データが多いほどSQLは遅くなります。
3. インデックスが無いとSQLはどれくらい遅くなるのか
次のような会員テーブルがあるとします。
id | name | age | email
---+------------+-----+-------------------
1 | 山田太郎 | 25 | taro@example.com
2 | 佐藤花子 | 19 | hanako@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋次郎 | 22 | jiro@example.com
5 | 田中美咲 | 28 | misaki@example.com
年齢が19歳の人を探すSQLを書きます。
SELECT *
FROM users
WHERE age = 19;
インデックスが無い場合、MySQLは全員の年齢を一人ずつ確認します。人数が1万人、10万人と増えるほど時間がかかります。
id | name | age | email
---+----------+-----+-------------------
2 | 佐藤花子 | 19 | hanako@example.com
4. インデックスを使うと何が変わるのか
次に、age列にインデックスを作成します。これは「年齢で探しやすくします」とMySQLに教える作業です。
CREATE INDEX idx_users_age
ON users(age);
この状態で同じSQLを実行すると、MySQLはインデックスを使って一瞬で場所を特定します。
SELECT *
FROM users
WHERE age = 19;
id | name | age | email
---+----------+-----+-------------------
2 | 佐藤花子 | 19 | hanako@example.com
結果は同じですが、内部の動きが大きく違います。これがインデックスによるSQL高速化です。
5. 遅いSQLが発生する代表的なインデックスの問題
MySQLで遅いSQLが発生する原因の多くは、次のようなインデックスの使い方ミスです。
- そもそもインデックスが作られていない
- 検索条件と違う列にインデックスがある
- インデックスが使われない書き方をしている
例えば、name列にインデックスがあるのに、ageで検索していると意味がありません。
6. WHERE句とインデックスの深い関係
インデックスは、主にWHERE句で使われます。WHERE句とは「条件を指定する部分」です。
SELECT name
FROM users
WHERE name = '山田太郎';
name列にインデックスがあれば高速ですが、次のような書き方だとインデックスが使われない場合があります。
SELECT name
FROM users
WHERE LEFT(name, 1) = '山';
これは「加工した結果」で探しているため、MySQLはインデックスを使えません。初心者が気づきにくいポイントです。
7. EXPLAINでSQLの動きを確認しよう
EXPLAINは、SQLがどのように実行されるかを教えてくれる命令です。インデックスが使われているかを確認できます。
EXPLAIN
SELECT *
FROM users
WHERE age = 25;
結果の中に「key」という項目があり、そこにインデックス名が表示されていれば、インデックスが使われています。
8. インデックスを作りすぎると逆に遅くなる理由
インデックスは便利ですが、作りすぎるとデータの追加や更新が遅くなります。
これは、名簿に新しい人を書くたびに、索引も全部書き直すようなものです。
MySQLのチューニングでは、「よく検索される列だけ」にインデックスを付けることが重要です。