Rails: проблема N + 1 ... нужны статистические данные - PullRequest
3 голосов
/ 17 июля 2011

После осознания того, что приложение страдает от проблемы N + 1 из-за ORM, я хотел бы получить больше информации об улучшениях, которые можно выполнить, и статистику по времени, сравниваемую до улучшений (с проблемой N + 1).) и после. Так какая разница во времени до и после таких улучшений? Может кто-нибудь дать мне ссылку на какой-нибудь документ, в котором анализируется проблема и получаются статистические данные об этом?

Ответы [ 2 ]

4 голосов
/ 17 июля 2011

Вам действительно не нужны статистические данные для этого, только математика. N + 1 (или лучше 1 + N) означает

  • 1 запрос для получения записи и
  • N запросов для получения всех записей, связанных с ним

Чем больше N, тем больше снижается производительность, особенно если ваши запросы отправляются по сети в удаленную базу данных. Вот почему проблемы N + 1 продолжают возникать в работе - они обычно незначительны в режиме разработки с небольшим объемом данных в БД, но, поскольку ваши данные растут в производстве до тысяч или миллионов строк, ваши запросы будут медленно душить ваш сервер. 1009 *

Вместо этого вы можете использовать

  • один запрос (через объединение) или
  • 2 запроса (один для основной записи, один для всех связанных записей

Первый запрос вернет больше данных, чем строго необходимо (данные первой записи будут дублироваться в каждой строке), но обычно это хороший компромисс. Второй запрос может быть немного громоздким для больших наборов данных, так как все внешние ключи передаются как один диапазон, но, опять же, это обычно компромисс, который стоит сделать.

Фактические числа зависят от слишком большого количества переменных, чтобы статистика была значимой. Количество или записи, версия БД, оборудование и т. Д. И т. Д.

Поскольку вы пометили этот вопрос с помощью rails, ActiveRecord отлично справляется с задачей, избегая N + 1 запросов, если вы знаете, как его использовать. Проверьте объяснение нетерпеливая загрузка .

0 голосов
/ 17 июля 2011

Разница во времени будет зависеть от того, сколько дополнительных операций выбора было выполнено из-за проблемы N + 1. Вот цитата из ответа на другой вопрос stackoverflow относительно N + 1 -

Цитировать начало

SELECT * FROM Cars;

/* for each car */
SELECT * FROM Wheel WHERE CarId = ?

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

Конец цитаты

В приведенном выше примере разница во времени будет зависеть от того, сколько записей автомобилей было в базе данных и сколько времени потребовалось для запроса таблицы «Колесо» каждый раз, когда код / ​​ORM извлекал новую запись. Если бы у вас было только 2 записи о машинах, то разница после устранения проблемы N + 1 была бы незначительной, но если у вас миллион записей о машинах, это оказало бы значительное влияние.

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