Tech Starlog

MySQL インデックス設計の基本

投稿日:2026/02/04

MySQLを使った開発で、こんな経験はありませんか?

  • インデックスを貼ったのにSQLが速くならない
  • どのカラムにインデックスを貼るべきか分からない
  • とりあえずインデックスを増やしている

インデックスは 正しく設計すれば高速化の武器 になりますが、
間違えると逆にパフォーマンスを悪化 させます。

本記事では、実務で使えるインデックス設計の基本ルール を解説します。


インデックスとは?

インデックスは、本の索引(目次) のようなものです。

  • インデックスなし:全ページを最初から探す
  • インデックスあり:目的のページに一瞬でジャンプ
CREATE INDEX idx_users_email ON users(email);

これにより、email での検索が高速になります。


なぜインデックス設計が重要なのか?

インデックスがない、または設計が悪いと、

  • フルテーブルスキャン(type: ALL)
  • レスポンス悪化
  • 本番障害の原因

になります。

👉 SQLチューニング = インデックス設計 と言っても過言ではありません。


インデックスを貼るべきカラム

① WHERE句でよく使われるカラム

SELECT * FROM users WHERE email = 'test@example.com';

👉 email にインデックスは 必須候補


② JOINで使われるカラム

SELECT *
FROM posts
JOIN users ON posts.user_id = users.id;

👉 posts.user_id にインデックスを貼る


③ ORDER BY / GROUP BY で使われるカラム

SELECT * FROM posts
ORDER BY created_at DESC;

👉 created_at にインデックス検討


インデックスを貼らなくていいカラム

❌ データ件数が少ない

  • 数十件〜数百件のテーブル
  • フルスキャンでも十分速い

❌ 更新頻度が極端に高い

  • ステータスフラグ
  • カウンタ系

👉 UPDATE/INSERTが遅くなる原因に


❌ 値の種類が少ない(低カーディナリティ)

status: 0 / 1
gender: male / female

👉 効果が出にくい


単一カラムインデックス vs 複合インデックス

単一カラムインデックス

CREATE INDEX idx_posts_user_id ON posts(user_id);
  • 単純
  • 判断しやすい

複合インデックス

CREATE INDEX idx_posts_user_created
ON posts(user_id, created_at);

👉 左から順番に使われる(最重要)


複合インデックスの注意点(左端一致)

(user_id, created_at)
SQL インデックス
WHERE user_id = 1
WHERE user_id = 1 AND created_at > now()
WHERE created_at > now()

SELECT * はインデックスを殺す

SELECT * FROM users WHERE email = 'test@example.com';

👇 改善

SELECT id, email FROM users WHERE email = 'test@example.com';

👉 カバリングインデックス が使える可能性あり


カバリングインデックスとは?

CREATE INDEX idx_users_email_name ON users(email, name);
SELECT email, name FROM users WHERE email = 'test@example.com';
  • データ本体を読まない
  • 高速

EXPLAINで Using index が表示される。


EXPLAINで必ず確認する

EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

チェックポイント:

  • type が ALL になっていないか
  • key が NULL ではないか
  • rows が多すぎないか

よくあるNGインデックス設計

❌ とりあえず全部貼る

  • インデックス肥大化
  • INSERT / UPDATE が遅くなる

❌ .envやconfigで管理しようとする

👉 インデックスは DB設計の責務


❌ 実行計画を見ない

👉 EXPLAINなしのインデックス設計は博打


インデックス追加の基本手順

  1. 遅いSQLを特定
  2. EXPLAINを確認
  3. WHERE / JOIN / ORDER BY を確認
  4. 必要最小限のインデックスを追加
  5. 再度EXPLAINで確認

Laravel開発での注意点

  • Eloquentの裏はSQL
  • migrationでインデックスを明示する
$table->index('user_id');

まとめ

インデックス設計で大切なのは、

  • 使われるSQLを基準に考える
  • 貼りすぎない
  • 必ずEXPLAINで確認する

ことです。

まずは、

  • WHERE
  • JOIN
  • ORDER BY

この3つから見直すだけで、 SQLのパフォーマンスは大きく改善 します。