Это связано с вопросом год и изменение назад.
Я приведу пример вопроса, который должен работать из коробки, если у вас есть доступный sqlite3: https://github.com/cairo140/rails-eager-loading-counts-demo p >
Инструкции по установке (для основной ветки)
git clone git://github.com/cairo140/rails-eager-loading-counts-demo.git
cd rails-eager-loading-counts-demo
rails s
У меня есть полная запись в репозитории, но мой общий вопрос в этом.
Как я могу подсчитать количество загрузок Rails, чтобы свести к минимуму запросы db по всей доске?
Проблема n+1
возникает всякий раз, когда вы используете #count
в ассоциации, несмотря на включение этой ассоциации через #includes(:associated)
в ActiveRelation. Обходным путем является использование #length
, но это хорошо работает только тогда, когда объект, на который он был вызван, уже загружен, не говоря уже о том, что я подозреваю, что он дублирует то, что уже сделали внутренности Rails. Кроме того, проблема с использованием #length
заключается в том, что она приводит к неудачной перегрузке, когда ассоциация не была загружена для начала, и счет - это все, что вам нужно.
Из файла readme:
Мы можем уклониться от этой проблемы, запустив #length в массиве posts (см. приложение), который уже загружен, но было бы неплохо иметь счетчик также доступным. Это не только более последовательное; он обеспечивает путь доступа, который не обязательно требует загрузки сообщений. Например, если у вас есть частичное, которое отображает счетчик, независимо от того, что, но в половине случаев частичное вызывается с сообщениями, загруженными и половину времени без, вы столкнулись со следующим сценарием:
- Использование
#count
- n
COUNT
запросы стиля, когда сообщения уже загружены- n
COUNT
запросы стиля, когда сообщения еще не загружены- Использование
#length
- Нулевые дополнительные запросы, когда сообщения уже загружены
- n
*
запросы стиля, когда сообщения еще не загруженыМежду этими двумя вариантами выбора нет доминирующего варианта. Но было бы неплохо пересмотреть #count, чтобы отложить до #length или получить доступ к длине, которая каким-то другим способом хранится за кулисами, чтобы мы могли иметь следующий сценарий:
- Использование измененного
#count
- Нулевые дополнительные запросы, когда сообщения уже загружены
- n
COUNT
запросы стиля, когда сообщения еще не загружены
Итак, какой правильный подход здесь? Есть ли что-то, что я забыл (очень, очень вероятно)?