我有一個跨越多個表的查詢,最終使用Active Model Serializer來呈現數據。目前很大一部分時間都花在串行器上,因爲我不得不從串行器本身查詢一些數據。我想找到一種方法來加速這一點,這可能不是使用AMS(這沒關係)。使用AMS加速大數據圖查詢和渲染
我的數據模型如下:
Location
-> Images
-> Recent Images
-> Days Images
Image
-> User
的recent_images
和days_images
是一樣的images
但有範圍做了where
由天,過濾和limit
至6
目前整個過程在本地需要大約15秒,生產需要2-4秒。我覺得我可以更快地完成這個任務,但我不完全確定如何修改我的代碼。
查詢來獲取Location
s是:
ids = @company
.locations
.active
.has_image_taken
.order(last_image_taken: :desc)
.page(page)
.per(per_page)
.pluck(:id)
Location.fetch_multi(ids)
fetch_multi
從identity_cache寶石。這些結果然後打串行是:
class V1::RecentLocationSerializer < ActiveModel::Serializer
has_many :recent_images, serializer: V1::RecentImageSerializer do
if scope[:view_user_photos]
object.fetch_recent_images.take(6)
else
ids = object.recent_images.where(user_id: scope[:current_user].id).limit(6).pluck(:id)
Image.fetch_multi(ids)
end
end
has_many :days_images do
if scope[:view_user_photos]
object.fetch_days_images
else
ids = object.days_images.where(user_id: scope[:current_user].id).pluck(:id)
Image.fetch_multi(ids)
end
end
end
近期和天圖像的範圍是:
scope :days_images, -> { includes(:user).active.where('date_uploaded > ?', DateTime.now.beginning_of_day).ordered_desc_by_date }
scope :recent_images, -> { includes(:user).active.ordered_desc_by_date }
我的問題是,如果你認爲我需要溝AMS所以我不必在序列化程序中進行查詢,如果是的話,你會如何推薦來渲染它?
查詢的慢部分是序列化程序必須執行讀取,因此它最終執行N + 1查詢。查詢位置很簡單,但序列化程序會爲每個位置執行一次查詢,1爲天圖像,1爲最近圖像。它迅速氣球,我希望找到一個更簡單的解決方案 – CWitty
正確的,我的觀點 - 一旦你有這樣一個足夠大的三向查詢,你建立一個表,代表所有搜索結果,當用戶上傳時更新一個圖像。假設相對較少的圖片被上傳和查詢很多,您可以針對查詢進行優化,並對上傳進行「搜索」,並使用觸發器/回調將圖片插入到所有搜索結果表格中。 – court3nay
你或許可以用一些聰明的事情做到這一點,但那會稍後咬你。製作一個代表搜索結果的新模型並製作一堆搜索結果。模型很便宜,代碼的複雜性和黑客很難(對於未來)。 – court3nay