3

我有一个特定要求,允许用户下载整个月的记录。这可以包括 15,000 到 20,000 条记录。我有一个优化的查询,但问题在于 html 渲染。基本上,它会遍历每条记录并按时间、日期、速度等对其进行格式化。问题是现在在 html 打印窗口上实际呈现带有内容的表格需要 6 分钟以上。如果我不能再优化查询或渲染,我还有什么其他选择?(请注意,将页面保存为缓存是没有意义的,因为如此大量的记录每月只会下载一次)

#query
@reports = unit.reports.where("reports.time > ? and reports.time < ?",range.begin, range.end)
@reports = @reports.includes(:alerts)


#view rendering:
- @reports.each do |r|
    %tr
      %td.num_col       #{Report.index_of(@reports, r)}
      - if @history_date
        %td.time_col      #{time_format(r.time)}
      - else
        %td.time_col      #{datetime_format(r.time)}
      - if @unit.unit_type.name == "MarineTrac"
        %td.latitude_col #{r.latitude.to_s}
        %td.longitude_col #{r.longitude.to_s}
        %td.address_col{:title => r.address_formatted} #{r.address_formatted(:street => false)}
      - else
        %td.street_col{:title => r.street}  #{r.street}
      %td.speed_col     #{speed_formatted(r)}
      %td.distance_col  #{r.distance}
      - if r.alerts.any?
        %td.alert_col
          %ul{:style => "margin: 0px; padding: 0px; list-style-type: none;"}
            - r.alerts.each do |alert|
              %li
                %span{:class => "#{alert.class_for_severity}"}= alert_full_str(alert)
      - else
        %td.alerts_col{:class => "severity_none"} None
      %td.signal_col #{r.signal_formatted}
      %td.fix_col #{r.gps_valid_str}
4

5 回答 5

2

我建议将报告生成提取到后台进程中。

基本上,使用Sidekiq之类的东西来将用户请求时生成的报告排入队列。然后,您可以立即返回并告诉他们“您的报告正在生成中。完成后您将收到一封电子邮件。”

您的 Sidekiq 工作人员将完成所有工作,并在完成后向用户发送一封电子邮件。

于 2013-07-08T22:19:15.110 回答
1

使用分页将结果分成可管理的块,我更喜欢Kaminari

我怀疑您将需要一个页面上的所有结果。为了解决这个问题,您可以使用分页和 jQuery无限滚动来在用户向下滚动页面时加载更多结果。这不仅会加快初始页面加载速度,而且如果用户只查找第一批结果,同时将所有内容都列在一个页面上,它会给服务器带来更少的压力。

即使滚动加载不是一个选项,您仍然可以使用 ajax 一次加载每个分页“页面”(比如每页 2,000 个结果?)。或者根据您的服务器有多强大以及您需要的结果有多快,您可以异步生成所有必需的 ajax 页面加载

于 2013-07-09T17:12:46.003 回答
0

将其导出为他们可以下载的 CSV。

于 2013-07-08T22:17:01.003 回答
0
  1. 如果需要查看,可以使用分页,这样每次只渲染部分结果 - 例如使用 will_paginate gem
  2. 如果您需要显示所有...尝试将其制作为 PDF,我认为 Prawn gem 是一个很好的选择

祝你好运

于 2013-07-09T16:56:15.893 回答
0

你应该看看http://jiren.github.io/StreamTable.js/stream.html。它最初获取“n”条记录,呈现页面,同时它不断从服务器加载剩余的数据,这样您就不必等待整个数据被加载以进行渲染。它还支持分页,还显示当前加载的数据量。

于 2013-07-09T18:09:49.360 回答