Нет, нет.Это предполагаемое поведение :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
, намного лучше для производительности.