我的Rails应用中有一个名为User
的模型,其中有一个属性name
假设我想查找Users
与特定字符串匹配的所有name
。
在Rails控制台中,我可以这样做:
选项1
User.where("name LIKE 'string'")
这非常快。
选项2
User.select{|u| u.name == "string"}
这非常慢。它适用于一个小型数据库,但如果你有数十万用户,这似乎首先尝试将所有Users
加载到内存中,然后在块中迭代它们。
这是否意味着选项2总是错误的? .select
的正确用例是什么,何时优于.where
?
我在我的应用程序中编写了一堆代码,使用.select
正常工作,但现在我尝试使用非常大的表,我看到我可能做错了。
答案 0 :(得分:14)
选择:http://apidock.com/rails/ActiveRecord/QueryMethods/select
“这将从数据库为范围构建一个对象数组,将它们转换为数组并使用Array#select迭代它们。”
所以,它很慢,因为它从数据库中取出一切,逐个将它们转换为Ruby对象,然后运行你给它们的块。如果您有一个包含100,000行的数据库表,则表示实例化100,000个ruby对象并在其上运行块。 Ruby很慢,所以这很慢。
使用where
基本上只是将一个SQL语句放在一起,让数据库处理它。数据库是快速的 - 如果速度是优先级,那么每当你可以推迟数据库时,你应该这样做。如果你有一个包含100,000行的数据库表,但只有10个匹配你的where
查询,那么数据库将处理过滤,而Ruby只返回10行,因此只需要实例化10个Ruby对象,而不是100,000。
几乎总是,您需要使用where
而不是select
。那么,你什么时候可以选择?当你想根据一些相当难以翻译成SQL的ruby条件过滤相对少量的记录时,你会使用它(通常与where
一起使用)。
示例:
User.where(account_cancelled: true).select do |u|
# perform complex ruby logic on user
# that would be hard to do with plain SQL
# (note, this will only act on the subset of
# users returned from the where clause)
end
因此,只要您合理地使用where
而不是select
,就应该这样做。
(还有第二次使用文档中提到的select
:“修改查询的SELECT语句,以便只检索某些字段” - 但这不是你在问题中处理的用途)