【发布时间】:2013-11-19 08:43:23
【问题描述】:
我尝试优化一些查询(Rails 2.3.18)
这是我的测试用例:
class Post
belongs_to :category
belongs_to :user
named_scope :public, :conditions => ["#{Post.table_name}.public = ?", true]
named_scope :of_user, lambda {|u|
{ :conditions => ["#{Post.table_name}.user_id = ?", u] }
}
end
class Category
has_many :posts
end
class User
has_many :posts
end
我的查询很简单:获取所有具有用户公开帖子的类别。
def categories
Post.of_user(u).public.map(&:category)
end
SELECT * FROM posts WHERE posts.user_id = 123 AND posts.public = 1
SELECT * FROM categories WHERE category_id = 4
SELECT * FROM categories WHERE category_id = 5
SELECT * FROM categories WHERE category_id = 6
我们现在有 1 个帖子查询,每个类别有 n 个查询。
使用:include 可以提高效率:
def categories
Post.of_user(u).public.find(:all, :include => :category).map(&:category)
end
SELECT * FROM posts WHERE posts.user_id = 123 AND posts.public = 1
SELECT * FROM categories WHERE category_id IN (4,5,6)
现在,我们只有 2 个查询:一个用于帖子,一个用于类别。
使用proxy_options 可以提高效率:
def categories
proxy_options = Post.of_user(u).public.proxy_options
# Returns { :conditions => "posts.user_id = 123 AND posts.public = 1" }
proxy_options[:joins] = "INNER JOIN #{Post.table_name}
ON #{Post.table_name}.category_id = #{Category.table_name}.id"
return Category.find(:all, proxy_options)
end
SELECT * FROM categories INNER JOIN posts ON posts.category_id = category.id
WHERE posts.user_id = 123 AND posts.public = 1
它有效,我只有 1 个查询,但我发现这种方法“丑陋”。
“通过关联使用named_scope”还有其他方法吗?
【问题讨论】:
标签: mysql sql ruby-on-rails ruby ruby-on-rails-2