Django, как реализовать поле, которое будет фильтроваться в каждом запросе - PullRequest
0 голосов
/ 04 декабря 2011

У меня есть модель django, у которой есть поле со следующими свойствами:

  • Теперь реализовано с использованием CharField, max_length = 1
  • поле перечисления с 4 вариантами A, B, C, D
  • 90% объектов будут иметь значение A, остальные равны B, C, D
  • в 90% запросов B, C, D будут отфильтрованы, показывая только объекты с A
  • Может быть, будет 10000-50000 объектов
  • Загрузка - 95% операций чтения при некотором обновлении и создании новых объектов
  • Эта модель является центральной для моего приложения, поэтому практически все страницы имеют список или подробный вид.

Итак, 90% времени я отфильтровываю те же самые 10% объектов (+ независимо от того, что делает запрос над этой базовой фильтрацией, чтобы показать мне 10-100 объектов). Как лучше всего сделать производительность в Django? (Оптимизация одного запроса может не стоить усилий, но почему-то кажется расточительным постоянно фильтровать данные одинаково ...)

  • просто использовать filter ()? В любом случае фильтрация A может потребовать незначительных затрат, если предположить, что оптимизация запроса отбросит множество объектов, прежде чем проводить различие между A и остальными объектами
  • фильтр + индекс для поля?
  • фильтр + индекс + реализовать поле с определенным типом данных, чтобы индексирование работало лучше? Какой тип будет идеальным?
  • Наследование нескольких таблиц с фиктивной базой + A (базовая), B (базовая), ...? Объекты обрабатываются одинаково, но таблицы дочерних классов не требуют фильтрации для этого поля.
  • Что-то еще?

БД - это MySql с таблицами InnoDB. Я планирую провести тесты с фиктивными данными для сравнения реализаций, но я был бы признателен за любые отзывы и ссылки на соответствующую информацию. Код представления добавляет вещи, зависящие от пользователя / профиля, к выводу для каждого объекта (т. Е. Рейтинг, который пользователь мог дать), и поэтому я не уверен, сколько я могу кэшировать.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2011

Этот вопрос состоит из двух частей: что лучше с точки зрения эффективности и как писать код.

С точки зрения эффективности нет необходимости делать что-либо, кроме того, чтобы убедиться, что индексы базы данных включают полевы будете фильтровать дальше.Вам, вероятно, потребуется сделать хотя бы часть этого вручную: используйте что-то вроде панели инструментов django-debug-tool для отображения ваших запросов и создайте составные индексы, необходимые для этих запросов.

Для кодаЛучше всего создать пользовательский менеджер с методом, который фильтрует только объекты A:

class MyManager(models.Manager):
    def only_as(self):
        return self.filter(myfield='A')

...

MyModel.objects.only_as().filter(whatever=whatever)
0 голосов
/ 04 декабря 2011

Я думаю, что вы не должны ничего оптимизировать, пока это не будет медленным. Для этого размера данных я постараюсь использовать поле «фильтр + индекс». Я не знаю, сколько запросов в секунду у вас есть. Если это не достаточно быстро, идея с отдельными таблицами выглядит разумной. Также вы можете попробовать использовать своего рода кеш, чтобы разделить ваши данные по ключу (A, B, C, D). Но мой совет - использовать простое решение, пока оно не будет приемлемым.

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