From 3ce6dbf798963338f7c47037107969e6e3e92d58 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 9 Mar 2026 13:53:20 +0100 Subject: [PATCH] Mail: Remove redundant SQL queries (#5896) On my local test event, this saved 75 queries on sending an email due to an N+1 query problem in the metadata querying. --- src/pretix/base/services/mail.py | 12 ++++++++++++ src/pretix/base/services/placeholders.py | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 42565422e..f76533521 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -409,6 +409,18 @@ def mail_send_task(self, **kwargs) -> bool: outgoing_mail.inflight_since = now() outgoing_mail.save(update_fields=["status", "inflight_since"]) + # Performance optimization, saves database queries later on if we resolve the known relationships + if outgoing_mail.event_id: + assert outgoing_mail.event.organizer_id == outgoing_mail.organizer.pk + outgoing_mail.event.organizer = outgoing_mail.organizer + if outgoing_mail.order_id: + assert outgoing_mail.order.event_id == outgoing_mail.event_id + outgoing_mail.order.event = outgoing_mail.event + outgoing_mail.order.organizer = outgoing_mail.organizer + if outgoing_mail.orderposition_id: + assert outgoing_mail.orderposition.order_id == outgoing_mail.order_id + outgoing_mail.orderposition.order = outgoing_mail.order + headers = dict(outgoing_mail.headers) headers.setdefault('X-PX-Correlation', str(outgoing_mail.guid)) email = CustomEmail( diff --git a/src/pretix/base/services/placeholders.py b/src/pretix/base/services/placeholders.py index 8ce503dab..f9b81554d 100644 --- a/src/pretix/base/services/placeholders.py +++ b/src/pretix/base/services/placeholders.py @@ -24,6 +24,7 @@ import logging from datetime import timedelta from decimal import Decimal +from django.db.models import Prefetch, prefetch_related_objects from django.dispatch import receiver from django.utils.formats import date_format from django.utils.html import escape, mark_safe @@ -35,6 +36,7 @@ from pretix.base.forms.widgets import format_placeholders_help_text from pretix.base.i18n import ( LazyCurrencyNumber, LazyDate, LazyExpiresDate, LazyNumber, ) +from pretix.base.models import EventMetaValue from pretix.base.reldate import RelativeDateWrapper from pretix.base.settings import PERSON_NAME_SCHEMES, get_name_parts_localized from pretix.base.signals import ( @@ -752,6 +754,11 @@ def base_placeholders(sender, **kwargs): name_scheme['sample'][f] )) + prefetch_related_objects( + [sender], + Prefetch('meta_values', queryset=EventMetaValue.objects.select_related("property"), to_attr="meta_values_cached") + ) + prefetch_related_objects([sender.organizer], Prefetch('meta_properties')) for k, v in sender.meta_data.items(): ph.append(MarkdownTextPlaceholder( 'meta_%s' % k, ['event'], lambda event, k=k: event.meta_data[k],