【问题标题】:Optimize Database Query Rails优化数据库查询 Rails
【发布时间】:2014-12-22 17:21:26
【问题描述】:

所以我正在和我的几个朋友一起做一个需要加载大量种子数据的 Rails 项目。我在 JSON 文档中有种子数据,该文档现在包含不到 3200 个 JSON 对象,每个对象都有相同的 3 个字段名称。

我已经在 Rails 中解析并植入了这些数据,为每个 JSON 对象创建了一条新记录。我应该注意到该对象有几个has_many 关联。

问题是,在我用 JSON 文件植入数据库之后,当我尝试将所有 3200 条记录加载到页面中时(仅使用一个普通的 ModelName.all.each 块),加载时间是荒谬的.. .about 17826ms(17.8 秒)。

根据控制台,它显示(Views: 16252.4ms | ActiveRecord 1522.9ms)。我已经研究过实现急切加载和预加载(我仍在努力)。

我的问题是,如何进一步优化它?我已经尝试ModelName.preload(:associationName) 进行预加载,但这似乎根本没有改变响应时间(也许我做错了)。令我惊讶的是,3200 条记录并不是很多……为什么要花这么长时间?在项目的早期就加入像 Redis 这样更快的东西会是一个可行的选择吗?

【问题讨论】:

  • 您是否将ModelName.all.each 放在视图中?
  • 您能否粘贴示例模型数据和您说 ModelName.all 时正在执行的查询。同时粘贴相关型号代码。
  • @tagCincy ModelName.all 位于一个控制器变量中,该变量在视图中以each 调用

标签: sql ruby-on-rails json database activerecord


【解决方案1】:

您可能遇到n+1 问题,确保您获取控制器中的所有对象,但在视图中您正在访问一些需要额外惰性查询的关系,以解决您需要急切加载整个数据的问题,使用includes关键字

@all_objects_with_associations = SomeObject.includes(:some_association).all

另一个额外的级别是使用片段缓存,假设您不想分页(如果您使用的是 rails 4,它默认启用),您需要做的就是在模板顶部添加一个缓存块,以及您认为如果更改需要缓存失效的所有变量

cache @all_objects_with_associations do

要了解更多信息,您可以查看以下链接

Eager loading in rails
Fragment caching in rails

【讨论】:

    【解决方案2】:

    真正杀死速度的是视图。渲染许多对象当然需要时间。您应该对数据进行分页并一次显示有限数量的数据。这将减轻数据库和视图的压力。

    使用“will_paginate”进行分页。

    或者,您可以实现“垂直分页”,即在页面向下滚动到底部后进行 AJAX 调用以获取和附加更多结果。

    此外,我会查看视图并确保没有通过它进行数据库查询。如果是这样,我会尝试通过预先加载或以某种方式将它们移动到控制器来消除它们,即已经将数据发送到视图而不让视图获取数据。

    【讨论】:

    • 说的很好,我在考虑分页和垂直延迟加载,非常感谢您的建议!
    【解决方案3】:

    除了分页,您可以只从数据库中获取所需的字段,这将进一步提高您的性能。

    由于您的视图占用了很大的时间片,请考虑以下几点:

    • 使用部分、辅助方法(以简化视图逻辑)
    • 将渲染移动到客户端(从服务器端发送 JSON)
    • 添加缓存策略

    如果您可以发布有关您的观点的一些详细信息,这将有助于我们提供更多定制的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 2019-03-30
      • 2017-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多