こう 聞かれます
- 「遅い SQL を、
どう 調べて どう 直しますか」 - 「画面が
遅いと 言われ、 DB が 原因らしいと 分かりました。 次に 何を しますか」 - 「インデックスを
足せば 速くなりますか」 (裏から聞く形)
面接官が 見ている点
- 勘で
直さず、 どの SQL が どれだけ 時間を 食っているかを 先に 数で掴むか - 実行計画 (EXPLAIN) を
読んで、 遅い 理由を言えるか - インデックスの
ほかに、 書き方 や取り方を 変える 手を 持っているか - 直した
後に、 本番に 近い量で 測り、 書き込みへの 影響まで 確かめるか
短い答え
- まず遅い
クエリの 記録や 監視の 画面から、 1 回の 遅さだけでなく、 回数を かけた 全体の 時間を 多く 食っている SQL を 見つけます。 - 次に EXPLAIN で
実行計画を 読み、 表を 全部読んでいる、 並べ替えに 時間が かかっている、 読む行が 多すぎる、といった 遅い 理由を 特定します。 - 理由に
合わせて、 インデックスを 足す、 条件や 取り方を 書き直す、 取る 量を 減らす、の どれかを 選び、 本番に 近い量の データで 測ってから 出します。
この
少し 詳しい答え
どの SQL から直すか
DB には、
ここで
実行計画を読む
見つけた SQL のEXPLAIN を
- 表を
頭から 全部読んでいないか (全件の走査) - 使うと
思っていた インデックスが、 本当に 使われているか - 読む行の
見積もりが、 返す行に 比べて 多すぎないか - 並べ替えや
一時的な 表づくりに 時間を 使っていないか
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 *をやめて 要る 列だけにし、 件数を絞ります
本番に 近い量で測る
行の
トレードオフ
インデックスは
話す例は
よく ある間違い
- 実行計画を
見ずに、 インデックスを 足して終える 原因が 書き方 や取り方なら 効きません。 書き込みが 遅くなるだけの こともあります - 手元の
少ない データで 速くなったと判断する 本番の 量と 偏りでは、 計画も 時間も 変わります - いちばん遅い 1 本だけを見る
回数の 多い SQL の ほうが、 全体を 重くしている ことがあります
深掘りの問い
- 「インデックスが
あるのに 使われないのは、 なぜですか」 列に 関数を かけている、 型が 合わない、 複合インデックスの 先頭の 列を 条件に 使っていない、 返す行が 多くて 全部読むほうが 速いと DB が 判断した、 などを挙げます - 「急に
遅くなった ときは、 何を 疑いますか」 データの 増え方 や偏りの 変化、 DB が 計画に 使う 統計が 古い、 最近の 配備で SQL が 変わった、 ロックの 待ち、を 順に 見る、と答えます - 「SQL を
これ以上速く できないときは」結果を 前もって 作っておく、 キャッシュする、 重い 集計を 別の 時間に 回す、と答えます
