2

ユーザー、関係、投稿、いいねを含むアプリがあります。
私のモデルは次のとおりです。

class User
  has_many :posts
  has_many :likes
  has_many :relationships, :foreign_key => "follower_id", :dependent => :destroy
end

class Post
  belongs_to :user
  has_many :likes  
end

class Like
  belongs_to :user
  belongs_to :post
end

class Relationship
  belongs_to :follower, :class_name => "User"
  belongs_to :followed, :class_name => "User"
end

だから私は私の現在の投稿を好きな少なくとも100人のユーザーを見つけたいです:

friends = User.find(user.followers).likes.where(:post => @post, :limit => 100)

DBにユーザー、投稿、いいねなどがたくさんある場合、これは単純ですが最適化されていないクエリです。
クエリ(または複数のモデル)を最適化して、速度を上げ、クエリの実行時間を短縮するにはどうすればよいですか?

4

3 に答える 3

1

まず最初に行うことは、すべてのテーブルに適切なインデックスがあることを確認することです。

したがって、テーブルの結合に使用されるすべての主キーと外部キーにインデックスが必要です。そしてもちろん、ソートやフィルターに使用する可能性のあるこれらのテーブルのフィールドにインデックスを付ける必要があります。

それ以外では、データベーススキーマに問題はありません。

ただし、非リレーショナルデータベースを調べたい場合は、多くの開発者がNoSQLストレージを使用して、メインの投稿が1つあるような問題を抱えていますが、いいねやコメントなどがいくつもある可能性があります。リレーショナルDB構造の異なるテーブルからこの情報を組み立てる必要はなく、単一の投稿のツリー構造全体を含むJSONなどの単一のNoSQLドキュメントエントリを維持するのは非常に簡単です。

于 2012-09-10T17:01:42.313 に答える
0

私はマイクに同意します。スキーマは良さそうですが、いくつかのインデックスを追加する必要があります。

実際にパフォーマンスの問題が発生した場合、最善のオプションは、一部のデータを非正規化することです(つまり、一部のクエリを事前に計算して結果をキャッシュします)。

キャッシュの明らかな候補は、特定のユーザーまたは投稿の「いいね」の数を保存することです。誰かが「いいね」をクリックするたびにこれを更新することも、cronジョブなどを介してカウントを更新することもできます。そうすれば、実際にJOINクエリを実行しなくても、「このような234人」をすばやく報告できます。たまに再計算するだけで、保存されているカウントが同期しなくなる可能性がありますが、それはこのアプリケーションにとってそれほど大きな問題ではありません(銀行口座の残高ではありません!)。

于 2012-09-10T17:10:07.127 に答える
0

インデックスを作成し、積極的な読み込みを使用してみてください。何かのようなもの

users = User.includes(:likes => [:post]).find(user.followers)
friends = users.where(:post => @post).limit(100)

データが大量にある場合は、find_in_batchesを使用して、Activerecordメモリがバッチトランザクションごとに解放されるため、メモリ消費を節約します。

于 2012-09-10T17:47:24.283 に答える