2010-08-20 74 views
0

在使用activeRecord的Rails中,为什么连接查询被认为是不好的。Rails优化问题

例如

在这里,我试图找到属于某一类公司的数量。


    class Company ActiveRecord::Base 
    has_one :company_profile 
    end 

找到公司数量为特定CATEGORY_ID

 
number_of_companies = Company.find(:all, :joins=>:company_profile, :conditions=>["(company_profiles.category_id = #{c_id}) AND is_published = true"]) 

这怎么可能是更好的还是仅仅是设计不良?

 

    company_profiles = CompanyProfile.find_all_by_category_id(c_id) 
    companies = [] 
    company_profiles.each{|c_profile| companies.push(c_profile.company) } 
 

第一个请求创建单个查询,而我会为第二个案例运行几个查询不是更好。

有人能解释为什么连接被认为是Rails的不好的做法,提前

+1

您可以添加一些参考吗?我不知道这样的意见通常是否持有--AFAIK,除非你需要它,但是当你确实需要它时(通常是出于性能原因),你应该绝对考虑它 - 这就是为什么它在那里的原因。也就是说,我认为你给出的具体例子可能用count()和适当的条件最有效地处理。 (如果你只需要一个号码,那就是) – 2010-08-20 07:33:15

+0

我似乎在这里找到了一些帮助 http://akitaonrails.com/2008/05/25/rolling-with-rails-2-1-the-first- full-tutorial-part-2 – Sid 2010-08-20 08:31:55

+0

似乎没有通用的规则来反对使用连接,但是当您有很多连接时,这意味着您的关联没有正确设计。 – Sid 2010-08-20 08:34:14

回答

1

据我所知,没有这样的规则。规则是尽可能少地使用数据库,并且使用连接为rails提供适当的工具。

上面Sam给出的例子是示例性的。简单的代码,但幕后的轨道必须做两个查询,而不是只有一个使用连接。

如果有一条想法,我认为是相关的规则,是尽可能避免SQL并尽可能使用rails方式。这使您的代码数据库不可知(因为rails会为您处理差异)。但有时甚至是不可避免的。

归结为良好的数据库设计,创建正确的索引(您需要在迁移中手动定义),并且有时需要大型嵌套结构/连接。

0

谢谢如果你只是想找到一个类别中的所有你需要做的企业数量是找到类别然后调用关联名称和大小,因为它会返回一个数组。

@category = Category.find(params[:id]) 
@category.companies.size 
+0

我明白,我的问题旨在了解为什么连接查询被认为是不好的。对不起,如果我的问题不是很清楚。 – Sid 2010-08-20 07:10:04

+0

我认为你比它更难,因为相当简单的加入会增加两倍的工作量,如果你坚持一个模型的一半工作。 – s84 2010-08-20 07:24:10

+0

你应该写'@category = Category.find(params [:id],:include =>:companies)'否则你打两次数据库。关于你上面的评论:实际上恰恰相反。 – nathanvda 2010-08-20 08:51:57

1

加入查询并不坏,事实上,它们都很好,ActiveRecord也有它的核心。你不需要闯入find_by_sql来使用它们,像include这样的选项将会为你处理它。你可以留在ORM中,这给了可读性和易用性,同时大部分仍然创建非常高效的SQL(假设你的索引是正确的!)

底线 - 你需要做裸最少的数据库操作。连接是让数据库为您付出沉重代价并降低您执行的查询数量的好方法。

顺便提一下,DataMapper的和阿雷尔(在Rails的查询引擎3)配备了大量的延迟加载 - 这意味着代码,如:

@category = Category.find(params[:id]) 
@category.companies.size 

最有可能导致连接查询,只有做了COUNT操作,因为第一行不会导致查询被发送到数据库。