我一整天都在試圖重構我的查詢。需要花費幾分鐘的時間才能載入20個記錄。起初,我責備查詢這個計算器後:在rails中重構一個昂貴的查詢
rails - using Rails.cache gives error
然而,做了一些測試後,我意識到,查詢被加載速度非常快,並且是不是罪魁禍首。
然後,我責備它雷,因爲我認爲這是雷填充幾千條記錄到Ruby對象,因爲我在這個崗位解釋說:
但是,這是錯誤的了。 Kaminari一次只加載20條記錄(我使用記錄器來檢查加載的報告數量,並顯示20條記錄)。
所以最後我想我找到了真正的罪魁禍首。這是在該頁面分頁期間發生的另一個查詢。我意識到,這個查詢花費超過20秒加載每次運行時間:
def virtual_fence_duration
inside_fence_time = nil
outside_fence_time = nil
outside_fence_time = self.time
previous_reports = Report.where{(time < my{self.time}) &
(unit_id == my{self.unit_id})}.order('time desc')
previous_reports.each do |report|
alerts = report.alerts.collect { |a| a.code_name }
if alerts.include? "Inside virtual fence"
inside_fence_time = report.time
break
end
end
if inside_fence_time && outside_fence_time
"Virtual Fence Elapsed Time: #{(((outside_fence_time - inside_fence_time).to_i).to_f/60.0).ceil} minutes"
else
""
end
end
基本上,這種方法被調用時,有一個警示,即「外虛擬圍欄」。我儲存時間。然後我查詢它之前的所有報告(報告has_many警報)。然後,我使用ruby的每個迭代器遍歷每個報告,然後使用與這些報告相關的警報來查找「在虛擬圍欄內」的警報。然後我將這個報告的時間存儲起來,並把這兩個時間區別開來。如果在兩個持續時間之間有很多報道,這個邏輯似乎是永久的。有沒有更有效的方法來做到這一點在SQL(MySQL)或紅寶石?
那'where'語法不是標準的ActiveRecord,你使用squeel嗎?另外,是'報警'報告的一個'has_many'關聯? – PinnyM 2013-03-20 21:15:45
@PinnyM是的,它似乎正在使用squeel。如果它導致性能問題,那麼我不介意從查詢中刪除它。是的一個報告has_many警報 – JohnMerlino 2013-03-20 21:18:52