遅い SQL を、どう調べてどう直しますか

勘で直さず、まず記録から全体の時間を多く食っている SQL を見つけ、EXPLAIN で実行計画を読み、原因に合った手 (インデックス、書き方、取り方) を選んで、本番に近い量で測ってから出す、と答える問い。インデックスを足すことの代償と、出した後の確かめまで話します。

まず 4 択で考える

2 問

答えに入れるべき考えを選びます。選ぶと、すぐに正誤と解説が出ます。そのあと下の欄で、自分の言葉で答えてみます。

  1. 問 1DB が重いとき、どの SQL から直すかの決め方として正しいものはどれか

  2. 問 2一覧の画面で、1 万件目から 20 件を OFFSET で取る SQL が遅い。直し方として正しいものはどれか

2 問中 0 問に答えました

答えてみる

面接官に「遅い SQL を、どう調べてどう直しますか」と聞かれたつもりで、答えを見る前に自分の言葉で、声に出して答えてみます。

解説を読む

聞かれ方から関連するコースまで、この問いの解説を全部ここに置いています。

こう聞かれます

  • 「遅い SQL を、どう調べてどう直しますか」
  • 「画面が遅いと言われ、DB が原因らしいと分かりました。次に何をしますか」
  • 「インデックスを足せば速くなりますか」(裏から聞く形)

面接官が見ている点

  • 勘で直さず、どの SQL がどれだけ時間を食っているかを先に数で掴むか
  • 実行計画 (EXPLAIN) を読んで、遅い理由を言えるか
  • インデックスのほかに、書き方や取り方を変える手を持っているか
  • 直した後に、本番に近い量で測り、書き込みへの影響まで確かめるか

短い答え

  • まず遅いクエリの記録や監視の画面から、1 回の遅さだけでなく、回数をかけた全体の時間を多く食っている SQL を見つけます。
  • 次に EXPLAIN で実行計画を読み、表を全部読んでいる、並べ替えに時間がかかっている、読む行が多すぎる、といった遅い理由を特定します。
  • 理由に合わせて、インデックスを足す、条件や取り方を書き直す、取る量を減らす、のどれかを選び、本番に近い量のデータで測ってから出します。

この問いを含む分野をレッスンで練習する

レッスンを開く

少し詳しい答え

どの SQL から直すか

DB には、決めた時間より遅いクエリを記録する仕組みがあります。監視の道具でも、SQL ごとの回数と時間を見られます。

ここで大事なのは、1 回が 3 秒の SQL より、1 回 50 ミリ秒でも 1 分に何千回も流れる SQL のほうが、DB 全体を重くしていることがある点です。回数と 1 回の時間をかけた全体の時間で並べ、上から手を付けます。1 つの画面で同じ形の SQL が何十回も流れているなら、N+1 問題を疑います。

実行計画を読む

見つけた SQL の頭に EXPLAIN を付けると、DB がどう読むつもりか (実行計画) が出ます。見る所は次の通りです。

  • 表を頭から全部読んでいないか (全件の走査)
  • 使うと思っていたインデックスが、本当に使われているか
  • 読む行の見積もりが、返す行に比べて多すぎないか
  • 並べ替えや一時的な表づくりに時間を使っていないか

PostgreSQL の EXPLAIN ANALYZE のように、実際に流して時間を測る指定もあります。これは本当にクエリを実行するので、更新や削除の文に付けるときは気をつけます。

よくある原因と直し方

SQL クエリ

-- 列に関数をかけると、その列のインデックスが使われにくい
SELECT * FROM orders WHERE DATE(created_at) = '2026-10-01';

-- 列はそのまま、範囲で書く
SELECT id, total FROM orders
WHERE created_at >= '2026-10-01' AND created_at < '2026-10-02';
  • 条件の列にインデックスが無い、合っていない 複合インデックスは列の順番が効きます。等しいで絞る列を前に、範囲や並べ替えに使う列を後ろに置くのが基本です
  • 列に関数や型の変換をかけている 上の例のように、列をそのままにした書き方に直します
  • 深いページを OFFSET で取っている 1 万件目からの 20 件でも、DB は前の 1 万件を読んで捨てます。「前のページの最後の id より後」で取る書き方 (キーセット方式) に変えます
  • 要らない列や行まで取っている SELECT * をやめて要る列だけにし、件数を絞ります

本番に近い量で測る

行の少ない手元の DB では、全部読んでも速いので差が出ません。DB は表の大きさや値の偏りを見て計画を選ぶので、量が違うと計画そのものが変わることもあります。本番に近い量と偏りのデータで、直す前と後の実行計画と時間を並べてから出します。

トレードオフ

インデックスは読むのを速くしますが、書き込みのたびに更新されるので、書き込みは遅くなり、場所も取ります。似たインデックスが増えると、DB がどれを使うか迷うこともあります。足すときは、ほかの SQL でも使えるか、もう要らないインデックスは無いかも見ます。大きな表にインデックスを作るときは、読み書きを止めない作り方ができるかを、使う DB の文書で確かめます。

話す例は架空の例で構いません。「一覧の画面が遅く、記録を見ると深いページの OFFSET が原因だったので、id で続きを取る形に変えた」のように、見つけ方、原因、直し方、測った結果を 1 本の話にします。

よくある間違い

  • 実行計画を見ずに、インデックスを足して終える 原因が書き方や取り方なら効きません。書き込みが遅くなるだけのこともあります
  • 手元の少ないデータで速くなったと判断する本番の量と偏りでは、計画も時間も変わります
  • いちばん遅い 1 本だけを見る回数の多い SQL のほうが、全体を重くしていることがあります

深掘りの問い

  • 「インデックスがあるのに使われないのは、なぜですか」 列に関数をかけている、型が合わない、複合インデックスの先頭の列を条件に使っていない、返す行が多くて全部読むほうが速いと DB が判断した、などを挙げます
  • 「急に遅くなったときは、何を疑いますか」データの増え方や偏りの変化、DB が計画に使う統計が古い、最近の配備で SQL が変わった、ロックの待ち、を順に見る、と答えます
  • 「SQL をこれ以上速くできないときは」結果を前もって作っておく、キャッシュする、重い集計を別の時間に回す、と答えます

確認日 2026年10月30日書き手 小尾 知希 (講師)

技術面接問題の一覧へ戻る