这是有关ActiveRecord查询方法的问题:

  • first查找第一个记录(如果提供了参数,则查找第N个记录)。如果未定义顺序,它将通过主键进行排序。
  • take给出一条记录(如果提供了参数,则为N条记录),没有任何隐含的顺序。顺序将取决于数据库的实现。如果提供订单,将受到尊重。

  • 用例:
    例如,基于唯一属性从数据库检索记录。
    User.where(email: '[email protected]')
    

    这里,first生成
    SELECT "users".* FROM "users" WHERE "users"."email" = '[email protected]' ORDER BY "users"."id"` ASC LIMIT 1
    
    take生成
    SELECT "users".* FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1
    

    因此,如上所示,first添加了附加的排序子句。我想知道takefirst之间是否存在性能差异。
    take是否比first更快,反之亦然?

    最佳答案

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

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

  • 不必查找多个行可以节省多少时间。最糟糕的情况是需要对大表进行完全扫描,但是在扫描的早期发现了一个匹配的行。 “采取”将允许扫描停止。
  • 需要排序多少行才能找到ID最低的行。最糟糕的情况是表中的每一行都与条件匹配,并且需要包括在排序中。

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

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

    编辑:我只是添加,尽管这有点题外话,在您的示例中您也可以使用:
    User.find_by(email: '[email protected]')
    

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

    关于sql - 在Ruby on Rails中取得第一名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18496421/

    10-14 03:13