sql - 与 Ruby on Rails 中的首次性能对比

标签 sql ruby-on-rails activerecord ruby-on-rails-4

这是一个关于 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 .

    takefirst 快或相反亦然?

    最佳答案

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

    它更快的程度将根据以下因素而有所不同:

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

  • 还有一些其他因素需要考虑——例如,对于“第一次”查询,优化器可能能够通过扫描主键索引来访问表并检查每一行以查看它是否与条件匹配。如果出现这种情况的可能性非常高,那么如果查询优化器足够复杂,则可以避免对数据进行完整扫描和排序。

    在许多情况下,匹配记录很少,并且可以通过基于索引的访问来查找它们,您会发现差异很小(在您的示例中,“电子邮件”上有一个唯一索引)。但是,即使那样,我仍然会优先使用“take”。

    编辑:我会补充一点,虽然它有点离题,但在你的例子中你不妨使用:
    User.find_by(email: 'f@example.com')
    

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

    关于sql - 与 Ruby on Rails 中的首次性能对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18496421/

    相关文章:

    ruby-on-rails - 在 Rails 中装饰属性

    mysql - 'SELECT' 语句中的 'IF' - 根据列值选择输出值

    表中所选记录的一列上的 MySQL 时间差

    ruby-on-rails - 如何测试重定向到外部 URL?

    ruby - 如何在 Rails 之外的 Ruby 项目上加载 ActiveRecord 数据库任务?

    ruby-on-rails - 在 ActiveRecord 中包含 where 子句

    mysql - 更新内部左连接上的列

    mysql - SQLMap 在本地网络上非常慢

    ruby-on-rails - Bootstrap Rails 不工作

    ruby-on-rails - 如何在 Rails 3 中验证非模型表单?