原先 controller 裡面的 query 是這樣
@auctions = Auction.recent
view ( JSON api ) auction 裡面有一個 attribute 是 has_actual_price?
json.array! @auctions do |auction|
json.id auction.id
json.has_actual_price? auction.has_actual_price?
end
在 auction.rb
裡面 has_actual_price?
是這樣設計的
def has_actual_price?
auction_items.where("actual_price > 0").first.present?
end
這個資料庫裡面 auction 與 auction_items 各是幾百萬資料..。所以這樣設計會有 N+1 與 slow query 的疑慮。
我的解法是在
has_one :auction_item_with_actual_price, :conditions => "auction_items.actual_price > 0", :class_name => "AuctionItem"
把 controller 改成
@auctions = Auction.includes(:auction_item_with_actual_price).recent
這樣就榨出了接近 10 秒的 query time,要再快可以再對 has_one 限制 select 欄位,還會更快....