Orders API: optimize a common filter query

This commit is contained in:
Raphael Michel
2021-05-18 09:08:50 +02:00
parent f19a74990f
commit e19d79a2bf
2 changed files with 16 additions and 13 deletions

View File

@@ -45,6 +45,8 @@ Here is the currently recommended set of commands::
CREATE INDEX CONCURRENTLY pretix_addidx_order_comment CREATE INDEX CONCURRENTLY pretix_addidx_order_comment
ON pretixbase_order ON pretixbase_order
USING gin (upper("comment") gin_trgm_ops); USING gin (upper("comment") gin_trgm_ops);
CREATE INDEX CONCURRENTLY pretix_addidx_order_event_date
ON public.pretixbase_order (event_id, datetime DESC);
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_name CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_name
ON pretixbase_orderposition ON pretixbase_orderposition
USING gin (upper("attendee_name_cached") gin_trgm_ops); USING gin (upper("attendee_name_cached") gin_trgm_ops);

View File

@@ -27,7 +27,7 @@ from decimal import Decimal
import django_filters import django_filters
import pytz import pytz
from django.db import transaction from django.db import transaction
from django.db.models import Exists, F, OuterRef, Prefetch, Q from django.db.models import Exists, F, OuterRef, Prefetch, Q, Subquery
from django.db.models.functions import Coalesce, Concat from django.db.models.functions import Coalesce, Concat
from django.http import FileResponse, HttpResponse from django.http import FileResponse, HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
@@ -97,30 +97,31 @@ with scopes_disabled():
model = Order model = Order
fields = ['code', 'status', 'email', 'locale', 'testmode', 'require_approval'] fields = ['code', 'status', 'email', 'locale', 'testmode', 'require_approval']
@scopes_disabled()
def subevent_after_qs(self, qs, name, value): def subevent_after_qs(self, qs, name, value):
qs = qs.annotate( qs = qs.filter(
has_se_after=Exists( pk__in=Subquery(
OrderPosition.all.filter( OrderPosition.all.filter(
subevent_id__in=SubEvent.objects.filter( subevent_id__in=SubEvent.objects.filter(
Q(date_to__gt=value) | Q(date_from__gt=value, date_to__isnull=True), event=OuterRef(OuterRef('event_id')) Q(date_to__gt=value) | Q(date_from__gt=value, date_to__isnull=True),
event=self.request.event
).values_list('id'), ).values_list('id'),
order_id=OuterRef('pk'), ).values_list('id')
) )
) )
).filter(has_se_after=True)
return qs return qs
def subevent_before_qs(self, qs, name, value): def subevent_before_qs(self, qs, name, value):
qs = qs.annotate( qs = qs.filter(
has_se_before=Exists( pk__in=Subquery(
OrderPosition.all.filter( OrderPosition.all.filter(
subevent_id__in=SubEvent.objects.filter( subevent_id__in=SubEvent.objects.filter(
Q(date_from__lt=value), event=OuterRef(OuterRef('event_id')) Q(date_from__lt=value),
event=self.request.event
).values_list('id'), ).values_list('id'),
order_id=OuterRef('pk'), ).values_list('id')
) )
) )
).filter(has_se_before=True)
return qs return qs
def search_qs(self, qs, name, value): def search_qs(self, qs, name, value):