0

私のアプリ記事には、自己参照結合モデル article_relationships を介して多くの子または親記事があります

class Article < ActiveRecord::Base

  has_many  :parent_child_relationships,
            :class_name   => "ArticleRelationship",
            :foreign_key  => :child_id,
            :dependent    => :destroy
  has_many  :parents,
            :through    => :parent_child_relationships,
            :source     => :parent

  has_many  :child_parent_relationships,
            :class_name   => "ArticleRelationship",
            :foreign_key  => :parent_id,
            :dependent    => :destroy
  has_many  :children,
            :through    => :child_parent_relationships,
            :source     => :child
end

class ArticleRelationship < ActiveRecord::Base
  belongs_to :parent, :class_name => "Article"
  belongs_to :child, :class_name => "Article"
end

article テーブルを掘り下げる article_relationships に関するかなり複雑なクエリがあります。

ArticleRelationship.joins(:parent, :child).where("((articles.type IN (:parent_article_type) AND parent_id IN (:ids)) OR (children_article_relationships.type IN (:child_article_type) AND child_id IN (:ids)) AND (article_relationships.created_at > :date OR article_relationships.updated_at > :date))", {:parent_article_type => "Emotion", :child_article_type => "Gateway", :ids => [1,2,3,4], :date => "2010-01-01"})

これを効果的にインデックス化する方法はありますか?

4

1 に答える 1

0

したがって、読みやすくするために、

ArticleRelationship.joins(:parent, :child).
 where("((articles.type IN (:parent_article_type) AND parent_id IN (:ids)) OR
         (children_article_relationships.type IN (:child_article_type) AND child_id IN (:ids))
        AND (article_relationships.created_at > :date OR article_relationships.updated_at > :date))",
       { :parent_article_type => "Emotion",
         :child_article_type => "Gateway",
         :ids => [1,2,3,4], :date => "2010-01-01" })

問題は OR 演算子です。OR のため、最上位の AND 式の両方で、データベースはインデックスを使用できません。

  1. レコードが作成されると、updated_at フィールドも同じタイムスタンプに設定されるため、OR created_at を削除して、update_at にインデックスを付けることができます。
  2. 親 ID と子 ID を記事タイプでフィルタリングできる場合は、それらの OR を削除できます。ただし、インデックス化されていないクエリよりも時間がかからないように、ID リストを入力としてフィルタリングするのに多くの時間を費やさないように、十分に効率的に実行できることを確認してください。最初に 1. を試してから、updated_at インデックスでどれくらい時間がかかるかを確認してください。

1 と 2 の両方を行う場合は、updated_at、parent_id、child_id の 3 つのフィールドすべてで 1 つのインデックスを作成してください。

于 2012-05-08T12:45:39.787 に答える