Ruby on rails 用AMS加速大数据图的查询和绘制

Ruby on rails 用AMS加速大数据图的查询和绘制,ruby-on-rails,activerecord,active-model-serializers,Ruby On Rails,Activerecord,Active Model Serializers,我有一个跨越多个表的查询,最终使用活动模型序列化程序呈现数据。目前大部分时间都花在序列化程序中,因为我不得不从序列化程序本身中查询一些数据。我想找到一种加快速度的方法,可能不使用AMS(这没关系) 我的数据模型如下: Location -> Images -> Recent Images -> Days Images Image -> User 最近的图像和天的图像与图像相同,但有范围进行操作,其中按天过滤,并将限制为6 目前,整个过程在本地大约需要15

我有一个跨越多个表的查询,最终使用活动模型序列化程序呈现数据。目前大部分时间都花在序列化程序中,因为我不得不从序列化程序本身中查询一些数据。我想找到一种加快速度的方法,可能不使用AMS(这没关系)

我的数据模型如下:

Location
  -> Images
  -> Recent Images
  -> Days Images
Image
  -> User
最近的图像
天的图像
图像
相同,但有范围进行
操作,其中
按天过滤,并
限制为6

目前,整个过程在本地大约需要15秒,在生产中需要2-4秒。我觉得我可以更快地执行此操作,但不完全确定如何修改代码

获取
位置的查询是:

ids = @company
  .locations
  .active
  .has_image_taken
  .order(last_image_taken: :desc)
  .page(page)
  .per(per_page)
  .pluck(:id)
Location.fetch_multi(ids)
fetch\u multi
来自gem。然后,这些结果会命中序列化程序,即:

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

我的问题是,如果您认为我需要放弃AMS,这样我就不必在序列化程序中查询,如果是,您会建议如何呈现它?

我可能没有抓住要点-哪一部分比较慢?这些圆木看起来像什么?是否缺少数据库索引?我没有看到太多的连接,所以也许你只需要上传日期的索引(可能还有用户id)。我看不到有什么东西在做连载

您可以通过多种方式轻松地加快sql的速度,例如,使用用户活动布尔值更新映像的触发器(在ruby或sql中),以便转储该联接。(你应该把它包括在索引中)

或者只使用ID构建一个缓存表。有点像倒排索引(我也会在redis中这样做,但那就是我),它为每个用户/位置都有一行,在上传图像时更新


将工作推送到图像上载,而不是现在的位置,查看列表。

查询的缓慢部分是序列化程序必须执行提取,因此它最终执行N+1查询。对位置的查询很容易,但是序列化程序随后会对每个位置执行一个查询,1个查询天数图像,1个查询最近的图像。它迅速膨胀,我希望找到一个更简单的解决方案,对吧,我的观点是——一旦你有了这样一个足够大的三方查询,你就可以建立一个代表所有搜索结果的表,当用户上传图像时,你就可以更新这个表。假设上传的图像相对较少,查询较多,您可以对查询进行优化,并在上传时执行“搜索”工作,使用触发器/回调将图像插入到所有搜索结果表中。您可以使用一些聪明的方法来完成这项工作,但这会对您造成不利影响。制作一个表示搜索结果的新模型,并制作一组。模型便宜,代码复杂,黑客很难(对未来的你们来说)。
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 }