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_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. If you can filter the parent ids and child ids by article type, you can remove those ORs. However, make sure you can do so efficiently enough to not spend more time filtering the id lists as input, that it doesn't take longer than the unindexed query. Try 1., first, and then see how long it takes with an updated_at index.

If you do both 1 and 2, be sure to create one index with all three fields, updated_at, parent_id, and child_id.

于 2012-05-08T12:45:39.787 回答