1

Я получаю преимущества использования загружаемой загрузки, чтобы избежать N + 1 при наборе массива объектов со связанными с ними записями, но важно ли использовать загружаемую загрузку при извлечении одной записи?Rails 4 Eager Load has_many Объединения для одиночного объекта

В моем случае

user has_many :addresses 
user has_many :skills 
user has_many :devices 
user has_many :authentications 

В шоу действия, я пытаюсь увидеть стойку мини-профайлером, если интересно использовать жадную загрузку

User.includes(:skills, :addresses, :devices, :authentications).find(params[:id]) 

Но я, кажется, то же самое количество запросов sql.

Любые советы по использованию надежной загрузки для такого случая или нет?

ответ

2

Попробуйте использовать Bullet gem для обнаружения неиспользованной или отсутствующей загруженной загрузки. Он предназначен для того, чтобы рассказать вам, есть ли впустую операторы include или неэффективные N + 1 запросы, где includes поможет.

Если есть проблема, его можно настроить для вывода на регистратор Rails, чтобы вы знали. Или вы можете показать ему уведомление в браузере на страницах, которые нуждаются в оптимизации.

3

Важно ли использовать загрузку при извлечении одной записи?

Для объединений на одном уровне в глубину, нет.

Если у вас есть вложенные ассоциации, да.

# class User 
has_many :skills 

# class Skill 
belongs_to :category 

# this code will fire N + 1 queries for skill->category 
user.skills.each do |skill| 
    puts skill.category 
end 

В этом случае лучше нетерпеливого нагрузки skills: :category

User.includes(skills: :category).find(id) 

Редактировать

Rails обеспечивают два способа избежать N + 1 запросов, на которые она ссылается как preload Инг и eager_load ing.

Preload запускает отдельные SQL-запросы для каждой коллекции.

Ожидаемая нагрузка пытается построить один массивный левый элемент SELECT для извлечения всех коллекций в 1 запросе.

Короткий вариант заключается в том, что includes позволяет Rails выбрать, какой из них использовать. Но вы можете заставить так или иначе.

User.eager_load(:skills, :addresses, :devices, :authentications).find(params[:id]) 

Необходимо получить все записи в 1 запросе.

Дальнейшее чтение:

+0

Но даже для ассоциаций 1 уровень глубокой, она не должна уменьшить количество SQL-запросов (от 5 к одному в этом примере)? –

+0

Похоже, вы ищете метод Rails 'eager_load'. Я отредактирую свой ответ. – messanjah