Tech Starlog

EXPLAINで見るSQLアンチパターン

投稿日:2026/02/05

本記事では、EXPLAINでよく遭遇するSQLアンチパターン
実例 → 問題点 → 改善方法 の流れで解説します。


EXPLAINで最低限見るべき項目

まず、以下の項目は必ず確認してください。

項目 意味
type アクセス方法(重要)
key 実際に使われたインデックス
rows 走査する想定行数
Extra 補足情報(Using whereなど)

👉 type / key / rows が分かれば8割は判断できます。


アンチパターン① type = ALL(フルテーブルスキャン)

EXPLAIN結果

type: ALL
key: NULL
rows: 120000

問題点

  • インデックスが使われていない
  • テーブル全件走査
  • データ増加とともに確実に遅くなる

よくあるSQL

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

改善方法

CREATE INDEX idx_users_email ON users(email);

改善後:

type: ref
key: idx_users_email
rows: 1

👉 type=ALLは最優先で潰す対象


アンチパターン② key = NULL(インデックスが使われていない)

EXPLAIN結果

type: range
key: NULL

問題点

  • インデックスは存在するが使われていない
  • SQLの書き方が原因のことが多い

よくある原因① 関数を使っている

SELECT * FROM users
WHERE DATE(created_at) = '2026-02-01';

改善

SELECT * FROM users
WHERE created_at >= '2026-02-01 00:00:00'
  AND created_at <  '2026-02-02 00:00:00';

👉 インデックスカラムに関数を使うと無効化されやすい


アンチパターン③ rows が異常に多い

EXPLAIN結果

type: ref
rows: 80000

問題点

  • インデックスは使われている
  • しかし絞り込みが弱い

原因例(低カーディナリティ)

WHERE status = 1
status: 0 / 1

改善方法

CREATE INDEX idx_orders_status_created
ON orders(status, created_at);

👉 複合インデックスで絞り込み精度を上げる


アンチパターン④ 複合インデックスの順番ミス

インデックス

(user_id, created_at)

使われないSQL

WHERE created_at > NOW()

EXPLAIN結果

key: NULL

改善

  • インデックス順を見直す
  • SQLをインデックスに合わせる

👉 左端一致ルールを守る


アンチパターン⑤ SELECT * による無駄なI/O

EXPLAIN結果

Extra: Using where

問題点

  • 必要以上にデータを取得
  • インデックスだけで完結できない

改善

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

良いEXPLAIN

Extra: Using index

👉 カバリングインデックスが効く


アンチパターン⑥ ORDER BY + filesort

EXPLAIN結果

Extra: Using filesort

問題点

  • メモリ or ディスクでソート
  • データ量次第で一気に遅くなる

よくあるSQL

SELECT *
FROM posts
ORDER BY created_at DESC;

改善

CREATE INDEX idx_posts_created_at ON posts(created_at);

👉 ORDER BYはインデックスで解決できることが多い


アンチパターン⑦ JOIN先テーブルがALL

EXPLAIN結果(一部)

table: posts
type: ALL

問題点

  • JOINキーにインデックスがない
  • JOINするたびに全件走査

改善

CREATE INDEX idx_posts_user_id ON posts(user_id);

👉 JOINカラムのインデックスは必須


実務でのEXPLAIN確認フロー

  1. 遅いSQLを特定
  2. EXPLAINを実行
  3. type が ALL か?
  4. key が使われているか?
  5. rows が多すぎないか?
  6. Extra に怪しい表示がないか?

まとめ

  • type = ALL
  • key = NULL
  • rows が多すぎる
  • Using filesort

これらを潰すだけでも、 SQLパフォーマンスは大きく改善 します。