Eager loading ассоциаций заранее загружает связанные записи и помогает избежать N+1 при их последующем использовании. preload использует отдельные запросы, eager_load — LEFT OUTER JOIN, includes выбирает способ в зависимости от запроса. После загрузки коллекции size использует её содержимое, а count без блока обычно выполняет SQL COUNT. Если нужны только количества, лучше рассмотреть групповую агрегацию или counter cache.
Что такое eager loading в контексте Ruby on Rails?
Предварительная загрузка ассоциаций Active Record, различия includes, preload и eager_load и важная оговорка о count и size.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
В контексте Active Record eager loading — предварительная загрузка связанных записей. Она помогает устранить N+1: один запрос получает публикации, а последующее обращение к комментариям каждой публикации иначе может вызвать ещё N запросов. Это не то же самое, что eager loading кода приложения при запуске Rails.
Предположим, Post имеет обычную ассоциацию has_many :comments:
Post.includes(:comments).limit(20).each do |post|
puts post.comments.size
post.comments.each { |comment| puts comment.id }
end
В таком простом случае Rails обычно выполнит запрос публикаций и отдельный запрос комментариев для выбранных публикаций. Последующий перебор использует уже загруженные объекты.
Стратегии различаются:
preload(:comments)загружает ассоциации отдельными запросами.eager_load(:comments)строит загрузку черезLEFT OUTER JOIN. Для коллекций это может сильно увеличить количество строк результата SQL.includes(:comments)выбирает между отдельной загрузкой и JOIN в зависимости от структуры запроса, например условий на связанную таблицу. Это не обещание автоматически найти самый дешёвый план.
Семантика методов описана в руководстве Active Record.
Важно не заменять size в примере на count без блока: такой count обычно выполняет SQL-подсчёт и может снова привести к N отдельным запросам даже после загрузки комментариев. size использует коллекцию, если она уже загружена; сам по себе вызов size на незагруженных ассоциациях не гарантирует устранения N+1. Документация CollectionProxy.
Если нужны только количества, загружать все комментарии в память необязательно: рассмотрите групповой COUNT по публикациям либо корректно поддерживаемый counter cache. При выборе решения оценивают не только число запросов, но и объём загруженных данных, время выполнения и расход памяти.