2014-09-29 98 views
0

什麼是返回從數據庫中唯一的記錄的最佳方法,請考慮以下因素:Ruby on Rails的唯一的記錄

@users = User.joins('LEFT JOIN subscriptions s ON users.id = s.user_id').includes(:profile).with_deleted.where("...", params[:conditions]).order("users.#{sort_column}" + ' ' + sort_direction).page params[:page] 

它有相當數量的加入的條件和分頁。所以現在用戶不是唯一的。這是使其具有唯一性的方法之一:

@users = @users.select('DISTINCT(users.id), users.created_at, users.deleted_at , ...') 

然而,這似乎是很慢的,我看到了很多的日誌,它告訴我,這不是一個好的查詢的解釋。

@users = @users.uniq{|u| [u.email]} 

這似乎是再運行一段時間(超時的網絡工作者),比上述聲明:

我也使用uniq的方法類似嘗試。什麼是解除複製記錄的正確方法?或者在這種情況下最佳的做法是什麼?

大約有120K個用戶,但是一次只能顯示25個,因此第一個/第二個語句中的.page方法。

回答

1

uniq是一個method of Array,所以它返回了整個120k用戶羣,並使用ruby逐個遍歷它們來檢查條件。這是過濾的錯誤方法。

另一方面,DISTINCT(users.id)SQL條件,這是由您的PostgreSQL服務器處理。這個應該執行得很快。如果需要一些相當長的時間,您應該仔細檢查您的索引(users.id,subscriptions.user_id,profiles.user_id以及基本上所有的主鍵和外鍵以及可以在您的where子句中查詢的屬性)。

的ActiveRecord hasdistinct方法speify唯一性約束,但its implementation只是使用arel做同樣的SQL DISTINCT查詢,所以應該沒有性能比較差。

P.S .:就像旁註一樣,您不需要在select查詢中枚舉users的所有所需字段。以下應爲您選擇users表的所有字段:

@users = @users.select('DISTINCT(users.id), users.*') 
0

檢查distinct

的文檔還指出,在第三個例子中,你正在加載的所有元素內存,然後做的操作,這是緩慢和內存餓了。

您應該選擇通過使用distinct來指示DBMS獨特的記錄。