这是有关ActiveRecord查询方法的问题:
first
take
用例:基于唯一属性从数据库检索记录,例如。
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或反之亦然?
通常,“获取”会更快,因为数据库不必识别所有符合条件的行,然后对它们进行排序并找到排序最低的行。“ take”允许数据库在发现单行后立即停止。
它更快的程度将根据以下因素而变化:
不必寻找多于一行可以节省多少时间。最坏的情况是需要对大表进行完全扫描,但是在扫描的早期发现了一个匹配的行。“采取”将允许扫描停止。
需要排序多少行才能找到ID最低的行。最糟糕的情况是表中的每一行都与条件匹配,并且需要将其包括在排序中。
还有其他一些因素需要考虑- 例如,对于“第一个”查询,优化器可能能够通过扫描主键索引来访问表,并检查每一行以查看其是否符合条件。如果很有可能,那么如果查询优化器足够复杂,就可以避免对数据进行完整扫描和排序。
在许多情况下,只有很少的匹配记录和基于索引的访问来查找它们,您会发现区别不大(示例中“电子邮件”上有唯一索引)。但是,即使到那时,我仍然会优先使用“ take”。
编辑:我只是添加,尽管这是一个有点题外话,在您的示例中,您也可以使用:
User.find_by(email: 'f@example.com')
生成的查询应该与take完全相同,但是我认为语义更加清晰。