某 school 反應 admin/students/edit
很慢
每次進入該頁面 progress bar 需要跑個 20 秒
此範例的問題點:
find
拿解決方式:
find
取得 fieldBefore: 358.31ms
After: 36.70 ms
ref: https://github.com/eduvo/openapply/pull/14478
newrelic
gem - bullet
https://github.com/flyerhzm/bullet
不過也要注意在加上 includes 時是否要需要加上限制條件,避免拿太多 objects 出來
explain
gem ruby-prof + gem ruby-prof-flamegraph + flamegraph generator
https://github.com/brendangregg/FlameGraph
可以使用 includes 修正
不過也要注意在加上 includes 時是否要需要加上限制條件,避免拿太多 objects 出來
gem - activerecord-import
https://github.com/zdennis/activerecord-import
可以加速 bulk insert & bulk update
並支援 MySQL 的 ON DUPLICATE KEY UPDATE
加 DB Index
explain
加上 status index 後
before | After | |
---|---|---|
Type | ALL | Ref |
Key | NULL | Index_pamoja_courses_on_status |
Rows | 169 | 104 |
部分 query 會需要多個欄位合併搜尋,可以考慮加 multiple-column Indexe
譬如 checklist_items 的
idx_checklist_items_unique_school_checklist_item_id_student_id (school_checklist_item_id,student_id,active) UNIQUE
可能是拿太多不需要的 row,可以用 where 或是 join 加上限制
Example 1: 譬如我需要的是 enrolled 的 pamoja_courses,那 query 就要下
PamojaCourse.where(status: 'enrolled')
而不是
PamojaCourse.all
Example 2: 譬如我需要的是「有 parent」 的 student
那就可以用 Student.joins(:parent)
來限制
可能是一次拿太多資料
可以利用 find_each 或 find_in_batches 分批拿
https://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_each
如果某個計算比較慢,但是參數不常變化
可以考慮放到 Rails 的 Cache 裡面
如果某段程式裡面含有執行速度較慢的程式,但不需立即得到結果
可以考慮把該段程式放到 background job 裡面
有一種情況是拿了不需要的資料,可以利用 select 或 pluck 拿需要的欄位即可
譬如
其他 ruby 程式的優化可以參考 https://github.com/JuanitoFatas/fast-ruby
https://github.com/evanphx/benchmark-ips
ActiveRecord::Base.logger = nil
Benchmark.ips do |x|
x.report('without select') do
Student.all.map{|s| s.name }
end
x.report('with select') do
Student.all.select(:first_name, :last_name, :preferred_name, :other_name).map{|s| s.name }
end
nil
end
https://github.com/github/scientist
class ScientistExperiment
include Scientist::Experiment
# ...
def publish(result)
puts "================================================="
puts "matced? #{result.matched?}"
puts "science.#{name}.control: #{result.control.duration}"
puts "science.#{name}.candidate: #{result.candidates.first.duration}"
puts "================================================="
end
end
=================================================
matced? true
science.family-roster-collect-ids.control: 4.199053999999705
science.family-roster-collect-ids.candidate: 0.04198200000064389
=================================================