3

ユーザーが 1 か月分のレコードをダウンロードできるようにする特定の要件があります。これには、15,000 ~ 20,000 レコードの範囲を含めることができます。最適化されたクエリがありますが、問題は html レンダリングにあります。基本的に、各レコードを調べて、時間、日付、速度などでフォーマットします。問題は、HTML 印刷ウィンドウでコンテンツを含むテーブルを実際にレンダリングするのに 6 分以上かかっていることです。クエリまたはレンダリングを最適化できなくなった場合、他にどのようなオプションがありますか? (このような大量のレコードは月に 1 回しかダウンロードされないため、ページをキャッシュとして保存しても意味がないことに注意してください)

#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 に答える
0

http://jiren.github.io/StreamTable.js/stream.htmlをご覧ください。最初に「n」個のレコードをフェッチし、ページをレンダリングすると同時にサーバーから残りのデータをロードし続けるため、レンダリングのためにデータ全体がロードされるのを待つ必要はありません。また、ページネーションのサポートもあり、現在読み込まれているデータの量も表示されます。

于 2013-07-09T18:09:49.360 に答える
0

ダウンロードできる CSV としてエクスポートします。

于 2013-07-08T22:17:01.003 に答える