In my app articles have many children or parent articles through a self referential joining model 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
I’ve got a fairly complex query on article_relationships that digs down into the article table
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"})
Is there any way I can index this effectively?
So, just for readability,
The problem is the OR operators. Because of the OR, in both of your top level AND expressions, the database cannot use an 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.