概要
開発されてからあまりメンテナンスされてないようなアプリの負荷対策をすることになった。
リリース当初に比べたらユーザ数も増えてることもあり、DBのCPU使用率があがってるのかなと思っていたが
今後もユーザ増加、運用されていくことを考えると対応する必要が出てきた。
行った調査
- SlowQueryの調査
- ボトルネックになっていそうな通信の調査
1. SlowQueryの調査
まず、SlowQueryがボトルネックになって使用率があがっていると想定して調べてみた。
いくつかのテーブルに有効なINDEXを追加することで改善を試みたが、 SlowQueryではなくなったもののDBの負荷は大きく変わらず高くなる状況だった。
2. ボトルネックになっていそうな通信の調査
今回有効だったのはこの調査。
通信の中で下記に該当するものを整理した。
- DBの負荷があがる時間帯で呼ばれているもの
- 機能的に呼ばれることが多いもの
その通信の中で実行されているQueryをすべてEXPLAINでまとめた。
例)
EXPLAIN SELECT * FROM users WHERE ID = 1;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
その結果、あるlogテーブルに対してのゲットが多く、かつINDEXが貼られていないことが判明した。
logテーブルは基本的にinsertのみで、INDEXを貼ることで遅くなるらしい…
なので、INDEXを貼らないのが普通らしい。
logテーブルとしては正しいのだが、logテーブルとして扱っていないのが問題。
これに対してなんかしらの対応を考えた。
対応案
a. logテーブルに対してゲットを行わないよう改修を行う
b. logテーブルにINDEXをはる
影響範囲や工数、予算との兼ね合いで、bの案で対応を行うことにした。
対応
INDEXがある場合、ない場合のEXPLAINを比較。
リリースしてから何年も経っているアプリのlogで件数もそこそこにあったため、INDEXを貼ることで検索の幅を狭められることが確認できた。
実際にlogテーブルにindexを貼ってみたところ、約1秒のQueryが0.1秒になり、DBへの負荷が減り通信全体も早くなった。
今回の学び
- 設計や命名定義はとても大事。logってつけてるなら、logらしく扱う設計にしよう。
- INDEXってすげー。なんにでもつければいいってものではないが、こうかはばつぐんだ。