ActiveRecord自定义查询vs find_by_sql加载

时间:2011-02-22 08:38:18

标签: ruby-on-rails activerecord load-time find-by-sql

我有一个看起来像这样的自定义查询

self.account.websites.find(:all,:joins => [:group_websites => {:group => :users}],:conditions=>["users.id =?",self])

其中self是用户对象

我设法为相同的

生成等效的 SQL

这里看起来如何

sql = "select * from websites INNER JOIN group_websites on group_websites.website_id = websites.id INNER JOIN groups on groups.id = group_websites.group_id INNER JOIN group_users ON (groups.id = group_users.group_id) INNER JOIN users on (users.id = group_users.user_id) where (websites.account_id = #{account_id} AND (users.id = #{user_id}))"

通过对 SQL和ActiveRecord 的理解,我认为(大多数人会同意)从上面的查询中获得的结果与从find_by_sql获得的结果相比可能需要更长的时间( sql)一个

但令人惊讶

当我跑上面两个  我发现ActiveRecord自定义查询在加载时间方面从ActiveRecord“find_by_sql”开始  这是测试结果

ActiveRecord自定义查询加载时间

  

网站加载(0.9毫秒)

     

网站专栏(1.0毫秒)

find_by_sql加载时间

  

网站加载(1.3毫秒)

     

网站专栏(1.0毫秒)

我再次重复测试,结果仍然相同(使用Custom Query赢得了战斗)

我知道区别不大但仍然无法弄清楚为什么普通的find_by_sql查询比自定义查询慢

任何人都可以分享这个。

非常感谢

此致 Viren Negi

2 个答案:

答案 0 :(得分:1)

使用查找案例,查询被参数化;这意味着数据库可以缓存查询计划,而不需要再次解析和编译查询。

使用find_by_sql情况,整个查询将作为字符串传递给数据库。这意味着数据库不能对查询结构执行缓存,并且每次都需要对其进行解析和编译。

我认为你可以测试一下:以这种方式尝试find_by_sql(参数化):

User.find_by_sql(["select * from websites INNER JOIN group_websites on group_websites.website_id = websites.id INNER JOIN groups on groups.id = group_websites.group_id INNER JOIN group_users ON (groups.id = group_users.group_id) INNER JOIN users on (users.id = group_users.user_id) where (websites.account_id = ? AND (users.id = ?))", account_id, users.id])

答案 1 :(得分:0)

嗯,原因可能很简单 - 使用自定义SQL,SQL查询会立即发送到数据库服务器以供执行。 请记住,Ruby是一种解释语言,因此Rails会根据您使用的ORM元语言生成新的SQL查询,然后才能将其发送到实际的数据库服务器以供执行。我想说框架生成查询所需的时间是0.1 ms。