Как избежать N + 1 с агрегатами DataMapper - PullRequest
2 голосов
/ 03 февраля 2011

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

@foos.each do |foo|
  puts foo.name
  puts foo.bars.count
end

Как мне избежать проблемы N + 1 в моих агрегатах? Другими словами, я не хочу новый SELECT COUNT(*)... запрос для каждой строки. Я мог бы просто создать представление SQL и сопоставить его с новой моделью, но есть ли более простой подход?

1 Ответ

1 голос
/ 03 февраля 2011

DataMpper нестабилен в этих вещах, поэтому я дам вам пару вариантов, которые могут сработать в зависимости от того, как выглядит ваш реальный код.

  1. Просто измените счетчик на размер, т.е. поместите foo.bars.size. Стратегическая нагрузка DM иногда может работать с этим подходом.

  2. Принудительная активная загрузка перед циклом @ foos.each, и изменение счетчика на размер , например

    @foos = Foo.all(...)
    @foos.bars.to_a
    @foos.each do | foo |
      puts foo.name
      puts foo.bars.size
    end
    
  3. Выполните необработанный SQL-запрос перед вашим циклом @ foos.each, который возвращает структуры с идентификаторами foo и столбцами, # отобразите их в Hash по идентификатору еды и поместите в цикл. (Мне приходилось прибегать к этому уровню бессмыслицы только один или два раза, я бы порекомендовал возиться с битами # 1 и 2 перед ним.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...