我一直致力于优化项目的数据库调用,我注意到下面两个相同的调用之间的性能存在“显着”差异:
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)
使用第一个版本的方法平均执行时间为300ms(其中总共调用了几千次操作),使用第二版本的方法执行时间约为550ms。这几乎是速度下降 100%。
我仔细检查了第二个版本生成的 SQL,它与第一个版本相同,但它在表列前面添加了表名。
- 为什么会减速? ActiveRecord 和 SQL 之间的转换真的使操作花费了近 2 倍吗?
- 如果我需要多次执行相同的操作并且不想增加开销,我是否需要坚持直接编写 SQL(甚至可能是存储过程)?
Thanks!
有几件事跳出来了。
首先,如果此代码被调用 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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)