3秒でわかる
テーブルの全行を先頭から読んで条件に合う行を探す読み方。インデックスが効いていないときに起きる、遅いクエリの典型的な原因です。
もう少し詳しく
どういうものか
フルスキャン(全表走査)は、テーブルに入っている行を先頭から最後まで順に読み、条件に合うものを拾っていく読み方です。索引を使わずに探すため、読む量はテーブルの行数に比例して増えます。100 万行のテーブルなら、1 行を取り出すためだけに 100 万行を読みます。
実行計画では type: ALL (MySQL) や Seq Scan (PostgreSQL) として現れます。
なぜ必要か
いつも悪いわけではない、という点が理解の肝です。数十行しかないマスタテーブルや、結果として全体の大半を返すクエリでは、索引をたどって本体を引き直すより、まとめて順に読むほうが速くなります。データベースが統計情報を見て、あえてフルスキャンを選ぶこともあります。問題になるのは、少数の行だけが欲しいのに全部を読んでいる場合です。
具体例
EXPLAIN SELECT * FROM users WHERE email = 'a@example.com';
-- type: ALL, rows: 1200000 索引が無いので全部読んでいる
CREATE INDEX idx_users_email ON users (email);
EXPLAIN SELECT * FROM users WHERE email = 'a@example.com';
-- type: ref, rows: 1 索引で 1 行に絞れたつまずきやすいところ
索引を張ってあるのにフルスキャンになる書き方があります。列を関数や計算でくるむと、索引に入っている値と比較できなくなるためです。
-- 索引が使われない
SELECT * FROM orders WHERE DATE(created_at) = '2026-01-01';
SELECT * FROM users WHERE email LIKE '%example.com';
-- 索引が使える形に直す
SELECT * FROM orders
WHERE created_at >= '2026-01-01' AND created_at < '2026-01-02';前方一致でない LIKE も同様に索引をたどれません。比較する型が違う場合(文字列の列に数値を渡すなど)も、暗黙の変換が入って全表走査に落ちます。
開発中は行数が少ないので、どんな書き方でも一瞬で返ります。本番でデータが増えてから急に遅くなるのはこのためで、実行計画は行数が少ないうちから見る習慣が要ります。
覚え方
索引が本の巻末索引、フルスキャンは 1 ページ目からめくる読み方です。数ページの冊子なら、めくったほうが速いこともあります。