Django: select_related () и использование памяти - PullRequest
2 голосов
/ 05 января 2012

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

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

Это из-за кеширования? Может быть, отдельные объекты данных используются для кэширования одинаковых экземпляров модели? Я не знаю, что еще думать.

Заранее спасибо.

1 Ответ

8 голосов
/ 05 января 2012

Это компромисс.Требуется время, чтобы отправить запрос в базу данных, базу данных для подготовки результатов, а затем отправить эти результаты обратно.select_related отрабатывает принцип, согласно которому самой дорогой частью этого процесса является цикл запроса и ответа, а не фактический запрос, поэтому он позволяет объединить то, что в противном случае было бы отдельным запросом, в один, поэтому существует только один запрос и ответвместо нескольких.

Однако, если ваш сервер баз данных недостаточно загружен (недостаточно оперативной памяти, вычислительной мощности и т. д.), на самом деле запрос большего размера может занять больше времени, чем цикл запроса и ответа.Если это так, вам, вероятно, нужно обновить сервер, но вместо этого не используйте select_related.

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

ОБНОВЛЕНИЕ (добавление дополнительных пояснений)

Запрос к базе данных на самом деле состоит из нескольких шагов:

  1. Приложение генерирует запрос (незначительно)
  2. Запрос отправляется на сервер базы данных (от миллисекунд до секунд)
  3. База данных обрабатывает запрос (от миллисекунд до секунд)
  4. Результаты запроса отправляются обратно в приложение (от миллисекунд до секунд)

В хорошо настроенной среде (достаточные ресурсы сервера, быстрые соединения) весь процесс завершается за несколько миллисекунд.Однако шаги 2 и 4, как правило, по-прежнему занимают больше времени, чем этап 3. Именно поэтому имеет смысл отправлять меньше более сложных запросов, чем несколько более простых запросов: узким местом обычно является транспортный уровень, а не обработка.

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

Тем не менееЕсли это так, то правильным ответом является исправление стороны базы данных: оптимизируйте базу данных и ее конфигурацию, добавьте больше ресурсов сервера и т. д. вместо того, чтобы вернуться к отправке нескольких простых запросов.

...