1

だから私はレールアプリを開発しており、フィードのページネーションに取り組んでいます。ロード時間が 1500 ミリ秒を超えていたので、それを行っている間、正しい方法で行っているかどうか疑問に思いました。私のコードは次のとおりです。

stories = Story.feed
@stories = Kaminari.paginate_array(stories).page(params[:page]).per(params[:pageSize])

これについていくつか質問があります。

  1. ページネーションStory.feedする必要がありますか、それとも必要なストーリーのみを返す何らかのメソッドがありますか?
  2. このロード時間は正常ですか?
  3. これを最適化するために他にできることは何ですか

(また、Story.feed はストーリー オブジェクトの配列を返します。そのコードは次のとおりです。

  def self.feed
    rawStories = Story.includes([:likes, :viewers, :user, :storyblocks]).all
    newFeaturedStories = rawStories.where(:featured => true).where(:updated_at.gte => (Date.today - 3)).desc(:created_at).entries
    normalStories = rawStories.not_in(:featured => true, :or => [:updated_at.gte => (Date.today - 3)]).desc(:created_at).entries
    newFeaturedStories.entries.concat(normalStories.entries)
  end

私はmongoidとmongodbを使用しています

4

3 に答える 3

0

を呼び出すとKaminari.paginate_arrayActiveRecord::Relationを呼び出すのと同様に、結果セット全体が DB からフェッチされ、メモリにロードされると思われますModel.all.to_a

これを回避するには、まずStory.feedクラス メソッドではなくスコープにする方法を見つけます。表面的には同じように見えますが、その違いは微妙ですが深いものです。Active Record スコープ vs クラス メソッドを参照してください。

次に、paginate_array連鎖カミナリpage()per()スコープを優先して溝を切ります.

例(あなたの簡略版):

class Article < ActiveRecord::Base

  scope :featured,    -> { where(featured: true) }
  scope :last_3_days, -> { where(:updated_at.gte => (Date.today - 3)).desc(:created_at) }
  scope :feed,        -> { featured.last_3_days }

そして、次のように簡単にページ付けします。

Article.feed.per(page_size).page(page)

LIMITこれの最大の利点は、Kaminari が生成された SQL に適切なand句を挿入して連鎖できることです。OFFSETこれにより、一致するすべてのレコードを返すのではなく、返される結果セットのサイズを表示する必要があるものだけに減らすことができます。

于 2013-07-19T07:08:33.330 に答える