Ответ 1
Нет, нет. Это предполагаемое поведение :include
, поскольку подход JOIN
в конечном итоге оказывается неэффективным.
Например, рассмотрим следующий сценарий: модель Post
имеет 3 поля, которые вам нужно выбрать, 2 поля для Comment
, и этот конкретный пост содержит 100 комментариев. Rails может запускать один запрос JOIN
по строкам:
SELECT post.id, post.title, post.author_id, comment.id, comment.body
FROM posts
INNER JOIN comments ON comment.post_id = post.id
WHERE post.id = 1
Это вернет следующую таблицу результатов:
post.id | post.title | post.author_id | comment.id | comment.body
---------+------------+----------------+------------+--------------
1 | Hello! | 1 | 1 | First!
1 | Hello! | 1 | 2 | Second!
1 | Hello! | 1 | 3 | Third!
1 | Hello! | 1 | 4 | Fourth!
...96 more...
Вы уже видите проблему. Подход с одним запросом JOIN
, хотя он возвращает нужные вам данные, возвращает его избыточно. Когда сервер базы данных отправляет результирующий набор в Rails, он будет отправлять идентификатор сообщения, заголовок и идентификатор автора 100 раз каждый. Предположим, что в Post
было 10 полей, которые вас интересовали, 8 из которых были текстовыми блоками. Eww. Это много данных. Передача данных из базы данных в Rails делает работу с обеих сторон, как в цикле ЦП, так и в ОЗУ, поэтому минимизация этой передачи данных важна для того, чтобы приложение выполнялось быстрее и компактнее.
Утилиты Rails сбивают числа, и большинство приложений работают лучше при использовании нескольких запросов, которые только извлекают каждый бит данных один раз, а не один запрос, который может стать чрезвычайно избыточным.
Конечно, наступит время в каждой жизни разработчика, когда соединение необходимо для выполнения сложных условий, и это может быть достигнуто путем замены :include
на :joins
. Однако для отношений предварительной выборки подход Rails, принятый в :include
, намного лучше для производительности.