我有一个跨越多个表的查询,最终使用Active Model Serializers来呈现数据。目前大部分时间都花在序列化器上,因为我不得不从序列化器本身查询一些数据。我想找到一种方法来加快速度,这可能不是使用AMS(这没关系)。
我的数据模型如下:
Location
-> Images
-> Recent Images
-> Days Images
Image
-> User
recent_images
和days_images
与images
相同,但有where
范围可按天数和limit
到6进行过滤。
目前整个过程在本地大约需要15秒,生产需要2-4秒。我觉得我可以更快地完成这项任务,但我并不完全确定如何修改我的代码。
获取Location
的查询是:
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,那么我就不必在序列化程序中进行查询,如果是这样,您会如何建议渲染它?
答案 0 :(得分:1)
我可能错过了这里的观点 - 哪个部分很慢?日志是什么样的?你错过了db索引吗?我没有看到很多连接,所以也许你只需要date_uploaded(也许是user_id)的索引。我没有看到任何正在进行大量序列化的内容。
您可以通过多种方式轻松加速sql - 例如,使用user_active布尔值更新图像的触发器(在ruby或sql中),以便您可以转储该连接。 (你将其包含在索引中)
或者使用其中的ID构建一个缓存表。有点像倒置索引(我也在redis中做,但那就是我),每个用户/位置都有一行,在上传图像时会更新。
将工作推送到图像上传而不是现在,查看列表。