2014-09-29 96 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独特的记录。