使用find_by_sql和普通的rails查询方法有什么区别?

时间:2011-09-01 07:44:38

标签: ruby-on-rails ruby-on-rails-3 activerecord query-optimization

我对我的rails应用程序中MySQL查询的执行时间有一点疑问。

我写过像

这样的查询
  @claims = Claim.joins('left join drugs on claims.ndc = drugs.ndcupchri left join pharmacies on claims.nabp = pharmacies.nabp').select('claims.*, drugs.*, pharmacies.* ').where('claims.member_id = '218').group(:ndc)

我用find_by_sql

写了一个相同的查询
   @sql = "SELECT claims.*, drugs.*, pharmacies.* FROM `claims` 
          left join drugs on claims.ndc = drugs.ndcupchri 
          left join pharmacies on claims.nabp = pharmacies.nabp 
          WHERE (claims.member_id = '218') GROUP BY ndc "

  @claims = Claim.find_by_sql(@sql)

有时我看到使用find_by_sql时,与其他查询相比,查询的执行时间非常快。它是否正确。

当涉及到以性能为导向时,上述哪种模式是更好的接受方法。请分享您的想法。

目前正在使用Rails 3.0.7

2 个答案:

答案 0 :(得分:2)

第一个查询是使用Arel。它提供可链接性和范围。 因此,如果您想要过滤更多数据,可以执行以下操作:

@claims.where(:id => 5)

使用find_by_sql无法实现上述功能。 Arel也使用Arel方法对sql查询进行优化。你可以在google上搜索Arel的其他优点。在rails 3.1中会有数据库查询结果的缓存(如果我错了,请纠正我)

如果你在sql中相当不错,那么find_by_sql总是会更优化,因为它直接在数据库上执行查询。但是,我们总是希望在生产力和绩效方面取得平衡。

答案 1 :(得分:0)

在你的情况下,joins子句过多,因为你没有在连接表上强加任何WHERE条件,只在索引表上,当你调用Claim.find_by_sql时,只会填充Claim对象。所以你的查询归结为

Claim.where(:member_id => 218)

它会比你的两个查询都快,因为没有连接被执行。

一般情况下,只应通过find_by_sql进行一些特定的查询。 Rails Arel接口足够灵活,可以实现大多数常用查询,并且调试那些庞大的SQL语句要容易得多。