ruby-on-rails - ActiveRecord 查询比直接 SQL 慢得多?

标签 ruby-on-rails ruby-on-rails-3 postgresql database-performance

我一直致力于优化我的项目的数据库调用,我注意到下面两个相同的调用在性能上存在“显着”差异:

connection = ActiveRecord::Base.connection()
pgresult = connection.execute(
  "SELECT SUM(my_column)
   FROM table
   WHERE id = #{id} 
   AND created_at BETWEEN '#{lower}' and '#{upper}'")

和第二个版本:

sum = Table.
      where(:id => id, :created_at => lower..upper).
      sum(:my_column)

使用第一个版本的方法平均执行时间为 300 毫秒(该操作在其中总共调用了数千次),而使用第二个版本的方法大约需要 550 毫秒。这几乎降低了 100% 的速度。

我仔细检查了第二个版本生成的 SQL,它与第一个版本相同,除了它在表列前加上表名。

  • 为什么减速? ActiveRecord 和 SQL 之间的转换是否真的使操作花费了将近 2 倍?
  • 如果我需要多次执行相同的操作并且不想增加开销,我是否需要坚持直接编写 SQL(甚至可能是存储过程)?

谢谢!

最佳答案

有几件事跳出来了。

首先,如果此代码被调用 2000 次并且需要额外运行 250 毫秒,那么将 Arel 转换为 SQL 的每次调用大约需要 0.125 毫秒,这并非不切实际。

其次,我不确定 Ruby 中 Range 的内部结构,但是 lower..upper 可能会进行范围大小等计算,这将是一个很大的问题性能下降。

您是否看到以下各项对性能的影响相同?

sum = Table.
      where(:id => id).
      where(:created_at => "BETWEEN ? and ?", lower, upper).
      sum(:my_column)

关于ruby-on-rails - ActiveRecord 查询比直接 SQL 慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11079783/

相关文章:

ruby-on-rails - Rails 确定来自 accepts_nested_attributes_for 对象的对象是否已更改?

sql - 带有附加列的 PostgreSQL INSERT FROM SELECT

ruby-on-rails - 从 Rails 模型生成 schema.rb(不带数据库)

javascript - 发送 AJAX 请求而不提交表单

ruby-on-rails - Rake:记录任何正在执行的任务

ruby-on-rails - 如何将参数从 radio_button_tags 传递到 Controller

ruby-on-rails - 在 View 中使用 I18n 而不是在控制台中使用 I18n 的 Rails 问题

javascript - 仅在 AJAX 创建帖子后,link_to 没有路由匹配

ruby-on-rails - Ruby - 查找具有相同属性的所有记录并将它们分组

php - 使用 'and' 或 'or' 作为变量在 PHP 中查询