現場で毎日使う画面を作っていて、「読み込み中……が長い」とフィードバックをいただいた。 測ると、最初の表示までに 10.4秒かかっていた。
扱っている数字は10万行に届く。なのでデータが多いせいだと思った。 集計を軽くするか、事前に計算しておくか。直す場所はもう決めたつもりでいた。
測ったら違った。
疑う前に、分解して測る
表示までの処理を段ごとに切って、それぞれ何秒かかっているかを取った。
データベース側は全部足して1.3秒だった。 残りの9秒はデータを取りに行く往復で消えていた。
1回の往復には、中身の重さと関係なく固定の費用がかかる。名乗って、確認されて、通されて、帰ってくる。 画面に必要な数字は何種類かに分かれていて、それぞれ別に取りに行っていた。 1本ずつは速い。ただ本数が多いので、合計は本数のほうで決まっていた。

速い問い合わせを何本も投げる構成は、遅い1本より遅くなることがある。 ここは自分でも意外だった。
やったことは2つ
ひとつは、中継を通る回数を減らしたこと。 最初に1回だけ通行証にあたるものを受け取り、以降しばらくは直接取りに行く形にした。
もうひとつは、2回目以降の見せ方を変えたこと。 前回の結果を手元に残しておいて、まずそれで画面を描く。新しいものは裏で取ってきて差し替える。 人が待つのは描画までで、更新は待たせない。
結果はこうなった。
- 初回の表示: 10.4秒 → 2.8秒
- ページ間の移動: 0.83秒
- 同じ条件をもう一度開いたとき: 即時
集計の中身には一行も手を入れていない。
本当にクエリが悪い場所もあった
同じ画面の中に、どこに余っていてどこで足りないかを突き合わせる集計がある。 これは1ヶ月ぶんで 72秒かかっていて、画面から呼べる状態ではなかった。
中身を見ると、品目ごとに「直近の記録を1件だけ取る」を対象の数だけ繰り返していた。 考え方は素直だが、繰り返しの回数がそのまま時間になる。
これをデータベース側で「まとめて並べ替えて、各グループの先頭だけ取る」1回の処理に置き換えたら 2.3秒になった。 あとから月ごとの表に切り出して索引も張った。
つまり同じ画面に両方あったことになる。往復の回数が効いている場所と、問い合わせ自体が悪い場所。 どちらも症状は「遅い」で、測るまで区別がつかなかった。
直す順番は初回から決める
改善幅がいちばん大きいのは、2回目以降を即時にしたところ。 ただ実際に効いたのは初回の10.4秒を縮めたほうだと思う。
人はそこで「このツールは重い」と判断する。一度そう思われると、あとで速くしても評価は戻らない。 逆に最初さえ我慢できる速さなら、残りは多少雑でも「速い」と言われる。

なので最適化の順番は、平均でも合計でもなく初回から決めることにした。
まとめ
- 遅いと指摘をもらったら、直す前に分解して測る。今回はデータベース側が1.3秒しかなかった
- 効いていたのは往復の回数。速い問い合わせを何本も投げる構成は、遅い1本より遅くなる
- ただし本当にクエリが悪い場所もある(72秒 → 2.3秒)。測らないと区別できない
- 直す順番は平均ではなく初回から
直したあとの数字より、直す前に「たぶんデータ量のせいだ」と決めていた自分のほうが問題だったと思う。 測る前の見立ては外れる。しかも外れたことに気づかないまま、関係ない場所を速くしてしまう。