Есть ли недостаток в добавлении нескольких индексов к модели в Django?

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

Когда я загружаю приборную панель в продакшене, на отрисовку представления уходит около 15 секунд. Другой приборной панели требуется 40. После анализа моего кода выяснилось, что мои запросы занимают очень много времени. Я думал, что это не так, поскольку моя модель Order содержит около 600k объектов, а фильтры order_date должны сократить их до 30k максимум.

Ниже представлена моя модель:

class Order(models.Model):
    order = models.IntegerField(db_index=True, default=0)
    region = models.CharField(max_length=3, default="")
    country = models.CharField(db_index=True, max_length=2, default="")
    order_date = models.DateTimeField(db_index=True, default=datetime.datetime.now)
    user_name = models.CharField(db_index=True, max_length=256, null=True)
    order_status = models.CharField(max_length=256, null=True)
    quote_status = models.CharField(max_length=256, null=True)
    purchase_status = models.CharField(max_length=256, null=True)
    q_to_r = models.FloatField(db_index=True, null=True)
    r_to_p = models.FloatField(db_index=True, null=True)

А вот фрагмент кода, на оценку которого уходит 15 секунд:

month = [4, 2022]

country = ["US", "CA", "UK"]

user_list = ["Eric", "Jane", "Mark"]
    
all_objects = Order.objects

first_data = all_objects.filter(order_date__month=month[0], order_date__year=month[1],
                                country__in=country, order_status__in=order_status, 
                                quote_status__in=quote_status,
                                purchase_status__in=purchase_status, user_name__in=user_list)

order_data = first_data.values_list("order", flat=True)
country_data = first_data.values_list("country", flat=True)

df = pd.DataFrame({"Order": order_data,
                   "Country": country_data})

В частности, экземпляр df занимает большую часть времени рендеринга представления.

Любой вклад будет оценен по достоинству. Я пытался добавить индексы в мою модель, безрезультатно.

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

  1. Фильтры в Django преобразуются в операторы WHERE с AND. Обычно можно ускорить выполнение таких запросов, поставив индекс на каждое поле, которое используется в операторе фильтрации, например, order_date, country, order_status, quote_status, purchase_status, user_name. Однако имейте в виду, что индекс, используемый СУБД, может варьироваться, и вам следует запустить профилировщик запросов, например, SQL EXPLAIN, чтобы понять, какие индексы дают ожидаемый эффект.

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

    .
  3. Для достижения наилучших результатов я рекомендую использовать профилировщик, например django-debug-toolbar, который может сильно помочь в определении узких мест в ваших запросах и поиске правильного подхода.

Вернуться на верх