Django: SQL-запросы выполняются медленно из-за сложных подзапросов, как их разделить или ускорить?

Мне нужно выполнить набор запросов со сложными подзапросами, как показано ниже. Выполнение запроса занимает значительное время. (8000 мс)

Я думаю, что замедление вызвано сложными подзапросами, но возможно ли разделить или ускорить один SQL-запрос без генерации N+1?

Используемый нами поиск в базе данных и медленный набор запросов в этот раз

# lookups.py
class Groonga(Lookup):
    lookup_name = "groonga"

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return "%s &@~ %s" % (lhs, rhs), params
# queryset
Video.objects.annotate(
    is_viewed=Exists(History.objects.filter(user=user, video=OuterRef("pk"))),
    is_favorited=Exists(
        Favorite.objects.filter(user=user, video=OuterRef("pk"))
    ),
    is_wl=Exists(
        Track.objects.filter(
            playlist__user=user, playlist__is_wl=True, video=OuterRef("pk")
        )
    ),
).filter(
    Q(title__groonga=value)
    | Q(tags__pk__in=Tag.objects.filter(name__groonga=value).values_list("pk")),
    is_public=True,
    published_at__lte=timezone.now(),
).order_by("-published_at").distinct()[:20]

SQL запрос и результаты EXPLAIN ANALYZE

Вы можете иметь сложные подзапросы, но это не первая атака, необходимая для лучшего выполнения. Вот виновник: Sort Method: external merge Disk: 12232kB. Вы выполняете сортировку на ДИСКЕ, а не в памяти. Вам нужно увеличить work_mem.

work_mem (целое число)

Устанавливает базовый максимальный объем памяти, который будет использоваться операцией запроса > (такой как сортировка или хэш-таблица) перед записью во временные дисковые файлы.

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