2011-07-17 4 views
3

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

ответ

4

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

  • 1 запрос, чтобы получить запись, и
  • N запросов, чтобы получить все записи, связанные с ним

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

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

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

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

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

Поскольку вы отметили этот вопрос рельсами, ActiveRecord делает хорошую работу, избегая N + 1 запросов, если вы знаете, как ее использовать. Ознакомьтесь с объяснением eager loading.

0

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

Quote Start

SELECT * FROM Cars; 

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

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

Quote End

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

Смежные вопросы