使用AMS加速大数据图形查询和渲染

时间:2017-04-19 14:18:40

标签: ruby-on-rails activerecord active-model-serializers

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

我的数据模型如下:

Location
  -> Images
  -> Recent Images
  -> Days Images
Image
  -> User

recent_imagesdays_imagesimages相同,但有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,那么我就不必在序列化程序中进行查询,如果是这样,您会如何建议渲染它?

1 个答案:

答案 0 :(得分:1)

我可能错过了这里的观点 - 哪个部分很慢?日志是什么样的?你错过了db索引吗?我没有看到很多连接,所以也许你只需要date_uploaded(也许是user_id)的索引。我没有看到任何正在进行大量序列化的内容。

您可以通过多种方式轻松加速sql - 例如,使用user_active布尔值更新图像的触发器(在ruby或sql中),以便您可以转储该连接。 (你将其包含在索引中)

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

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