这是一个关于 ActiveRecord 查询方法的问题:
first
查找第一条记录(如果提供了参数,则查找前 N 条记录)。如果没有定义顺序,它将按主键排序。 take
给出一条记录(如果提供了参数,则为 N 条记录),没有任何隐含的顺序。顺序将取决于数据库实现。如果提供订单,它将得到尊重。 用例:
根据唯一属性从数据库中检索记录,例如。
User.where(email: 'f@example.com')
这里,
first
产生SELECT "users".* FROM "users" WHERE "users"."email" = 'f@example.com' ORDER BY "users"."id"` ASC LIMIT 1
take
产生SELECT "users".* FROM "users" WHERE "users"."email" = 'f@example.com' LIMIT 1
如上所示
first
添加额外的排序子句。我想知道 take
之间是否存在性能差异对比 first
.是
take
比 first
快或相反亦然?
最佳答案
一般来说,“take”会更快,因为数据库不必识别所有符合条件的行,然后对它们进行排序并找到排序最低的行。 “take”允许数据库在找到单行后立即停止。
它更快的程度将根据以下因素而有所不同:
还有一些其他因素需要考虑——例如,对于“第一次”查询,优化器可能能够通过扫描主键索引来访问表并检查每一行以查看它是否与条件匹配。如果出现这种情况的可能性非常高,那么如果查询优化器足够复杂,则可以避免对数据进行完整扫描和排序。
在许多情况下,匹配记录很少,并且可以通过基于索引的访问来查找它们,您会发现差异很小(在您的示例中,“电子邮件”上有一个唯一索引)。但是,即使那样,我仍然会优先使用“take”。
编辑:我会补充一点,虽然它有点离题,但在你的例子中你不妨使用:
User.find_by(email: 'f@example.com')
生成的查询应该与 take 完全相同,但我认为语义更清晰一些。
关于sql - 与 Ruby on Rails 中的首次性能对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18496421/