admin

在Ruby on Rails中取得第一名

sql

这是有关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添加了附加的排序子句。我想知道takevs之间是否存在性能差异first

take快于first或反之亦然?


阅读 145

收藏
2021-05-10

共1个答案

admin

通常,“获取”会更快,因为数据库不必识别所有符合条件的行,然后对它们进行排序并找到排序最低的行。“ take”允许数据库在发现单行后立即停止。

它更快的程度将根据以下因素而变化:

  1. 不必寻找多于一行可以节省多少时间。最坏的情况是需要对大表进行完全扫描,但是在扫描的早期发现了一个匹配的行。“采取”将允许扫描停止。

  2. 需要排序多少行才能找到ID最低的行。最糟糕的情况是表中的每一行都与条件匹配,并且需要将其包括在排序中。

还有其他一些因素需要考虑-
例如,对于“第一个”查询,优化器可能能够通过扫描主键索引来访问表,并检查每一行以查看其是否符合条件。如果很有可能,那么如果查询优化器足够复杂,就可以避免对数据进行完整扫描和排序。

在许多情况下,只有很少的匹配记录和基于索引的访问来查找它们,您会发现区别不大(示例中“电子邮件”上有唯一索引)。但是,即使到那时,我仍然会优先使用“
take”。

编辑:我只是添加,尽管这是一个有点题外话,在您的示例中,您也可以使用:

User.find_by(email: 'f@example.com')

生成的查询应该与take完全相同,但是我认为语义更加清晰。

2021-05-10