Ruby Active Record присоединяется и включает в себя генерировать различные sql для подсчета - PullRequest
0 голосов
/ 19 октября 2018

Вот мои таблицы:

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

-

Role
id:          primary key
name:

Я выполняю следующие операторы с активной записью:

Оператор 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 имеет видnot null
  2. Учет count (*) без объединения имеет лучшую производительность и использование ресурсов

Я очень озадачен, почему эти два запроса генерируют разные SQL.А если быть более точным, почему объединение генерирует SQL с меньшей производительностью?

1 Ответ

0 голосов
/ 19 октября 2018

ActiveRecord просто не такой умный.Позвонив по номеру

User.joins(:role).size

, вы сообщаете это INNER JOIN таблице roles, а затем проверяете счет.

Он использует INNER JOIN даже для подсчета, потому что он недостаточно умен, чтобы выяснить, что, поскольку у вас есть внешний ключ И , столбец не может обнуляться И для таблицы roles нет условий, объединение на самом деле не нужно.

Вызов

User.includes(:role).size

не создает объединение, поскольку вы не говорите ActiveRecord о загрузке всехПользователи, у которых определена роль, и она использует левые соединения или отдельные запросы для загрузки ролей.

...