Railsアプリを6倍高速化した話
正確に言えば通常の6倍遅いRailsアプリケーションを通常の速度にした、といった感じです。
まず、こちらを見てください
Completed 200 OK in 3271ms (Views: 53.9ms | ActiveRecord: 2300.6ms)
あぁ・・・・・
ActiveRecord2300msって・・・・あと800msくらいよくわからない時間がある・・・
鈍速なのでレスポンスタイム500msを目指します。
計測
newrelic見るとだいたいどこがボトルネックか分かりました。
コントローラーでviewに投げる変数作るときにだいぶ時間食ってますね。
やった事
- activerecord周りの処理の見直し
- fragment cacheの使用
この2つでだいぶ速くなりました。
activerecord周りの処理
ログを見るとselect文が大量発生していました。
Article Load (4.2ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` = 1 LIMIT 1 Article Load (3.9ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` = 5 LIMIT 1 Article Load (3.2ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` = 61 LIMIT 1 Article Load (2.8ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` = 31 LIMIT 1 Article Load (3.1ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` = 78 LIMIT 1
まずこれをなんとかするためにこのsqlが発行される場所を見ました。そして該当箇所を探してincludesします。
Calendar.includes(article: [:tags])
これで発行されるsql文がスマートになりました。
SELECT `calendars`.* FROM `calendars` ORDER BY date DESC Article Load (1.7ms) SELECT `articles`.* FROM `articles` WHERE `articles`.`id` IN (1, 61, 27, 129, 127, 131, 142, 128, 30, 83, 84, 29, 85, 137, 19, 80, 28, 159, 78, 90, 35, 79, 149, 31, 134, 77, 87, 156, 163, 157, 133, 81, 17, 88, 138, 24, 151, 89, 93, 130, 152, 153, 154, 140, 161, 135, 145, 144, 155, 86, 82, 164, 41, 139, 132, 36, 162, 160, 95, 96, 62, 148, 166, 92, 25, 141, 165, 143, 136, 18, 21, 147, 20, 146, 34, 52, 150, 94, 46, 53, 91, 39, 23, 22, 38, 158, 167, 47, 33, 37, 42, 45, 63, 32, 43, 48, 40, 51, 49, 44, 168, 54, 56, 169, 179, 180, 184, 50, 65, 171, 172, 173, 177, 178, 181, 182, 183, 55, 170, 64, 66)
ここで時間は
Completed 200 OK in 1052ms (Views: 65.1ms | ActiveRecord: 124.4ms)
とりあえず3倍速ですね。
fragment cacheの使用
ボトルネックの該当viewは全ページに表示されるメニューだったので、キャッシュを使います。
該当viewを以下のように変更します。パーシャル化してあるのでこれだけでOKです。
<% cache("right_menu", skip_digest: true, expires_in: A_DAY) do %> #該当view <% end %>
これで時間を見ると
Completed 200 OK in 496ms (Views: 23.1ms | ActiveRecord: 41.9ms)
更に倍速の6倍速!目標に到達しました。
Chromeでの実測だとだいたい+1000msされるのですが、これはAnalyticsやFacebookの読み込みが影響しているようです。どうにかしたいです・・・・・