2010-08-20 105 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操作,因爲第一行不會導致查詢被髮送到數據庫。