Обновление модели при сохранении и подсчете объектов в ListView - что лучше с точки зрения производительности? - PullRequest
1 голос
/ 11 июля 2019

Я создаю скрипт на форуме. В настоящее время я пытаюсь оптимизировать вещи и ищу ответ от более опытных разработчиков.

Например - предположим, что мы работаем над ListView of Category, который должен перечислять все темы в одной категории форума. Для каждой темы в категории мы перечисляем такие поля, как:

  • Название темы

  • Автор темы

  • Количество сообщений

  • Количество просмотров

  • Информация о последнем сообщении (автор, дата)

Каков наилучший подход к производительности для подсчета количества постов? В настоящее время я думаю о 3 решениях.

  1. Использовать annotate() в наборе запросов
  2. добавить IntegerField posts_number к Thread модели. Увеличьте значение на save() в Post модели и уменьшите на delete()
  3. Используйте memcache для кэширования запросов SQL только для чтения и принудительного обновления кэша на каждой save() в Post модели.

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

1 Ответ

1 голос
/ 11 июля 2019

Я обычно обрабатываю количество сообщений в самой модели потока не как дополнительный model.field, а как метод или свойство и кеширую вычисленное значение один раз и аннулирую кеш для этого только потока , когда естьэто новое сообщение в этой теме.Таким образом,

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

И для вашего решения

  1. Аннотация работает быстрее, чем вычисление счетчика на поток в цикле for, но тогда вам придется считать его каждый раз, даже когда не было нового сообщения.

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

  3. Для вашего memcache решения я думаю, что лучше всего, когда они не были связаны друг с другом (новый пост в теме A не заставит вас пересчитать количество для всех потоков)

Кроме того, не рекомендуется обрабатывать обновление кэша в model.save, так как он вызывается постоянно (например, редактирование сообщения), лучше аннулировать и не обновлять кэш, где вы фактически создаете или удаляете сообщение (например, в админе и написании пользовательской формы, или в вашем представлении или serializer.perform_create или в сигналах, но не упускайте мягкие удаления и т. д.)

Обновление:

Поскольку ваш вопросо производительности вы должны взглянуть django ORM оптимизация doc самое главное select_related and prefetch_related

Кроме того, если вам не нужны объекты python после получения их из базы данных и просто нужно их значение не конвертировать их в объекты Python

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