Ruby Active Record加入并包括生成不同的sql以进行计数

时间:2018-10-19 11:25:10

标签: ruby-on-rails ruby activerecord rails-activerecord

这是我的桌子:

User
id:          primary key
user_name:
role_id:     foreign key     **NOT NULL**

-

Role
id:          primary key
name:

我正在使用Active Record执行以下语句:

声明1:

User.includes(:role).size
   (1.1ms)  SELECT COUNT(*) FROM "users"

声明2:

User.joins(:role).size
   (1.8ms)  SELECT COUNT(*) FROM "users" INNER JOIN "roles" ON "roles"."id" = "user"."role_id"

基于以下事实:

  1. 外键role_id不为空
  2. 不加入计数的count(*)具有更好的性能和资源使用率

我很困惑,为什么这两个查询生成不同的SQL。更准确地说,为什么联接生成性能较差的SQL?

1 个答案:

答案 0 :(得分:4)

ActiveRecord根本不那么聪明。通过致电

User.joins(:role).size

您正在将其告知INNER JOINroles,然后检查计数。

它甚至使用INNER JOIN进行计数,因为它不足以弄清楚由于您具有外键 AND ,因此该列不可为空 AND roles表上没有条件,实际上不需要联接。

通话

User.includes(:role).size

之所以不会生成联接,是因为您没有告诉ActiveRecord加载所有定义了角色的用户,而是使用左联接或单独的查询来加载角色。