Skip to content

Commit 3fde1ea

Browse files
scttcperclaude
andauthored
perf(issues): Avoid slow double-join in source-map-debug-blue-thunder-edition (#112627)
The `has_uploaded_some_artifact_with_a_debug_id` existence check joins DebugIdArtifactBundle -> ArtifactBundle -> ProjectArtifactBundle with only org_id + project_id filters. For large orgs this scans millions of rows in DebugIdArtifactBundle. Replace the double join with a correlated `EXISTS` subquery so Postgres can use the `(project_id, artifact_bundle)` composite index on ProjectArtifactBundle directly. Skip the query entirely when the event's own debug IDs already matched uploaded artifacts. fixes [SENTRY-2JS6](https://sentry.sentry.io/issues/4945181039/events/064fada92c3d47e2876e955f14f1a1b5/?project=1&referrer=previous-event&statsPeriod=14d) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 889b54d commit 3fde1ea

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

src/sentry/api/endpoints/source_map_debug_blue_thunder_edition.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Literal, TypedDict
22

33
import sentry_sdk
4+
from django.db.models import Exists, OuterRef
45
from django.utils.encoding import force_bytes, force_str
56
from drf_spectacular.utils import extend_schema
67
from packaging.version import Version
@@ -20,6 +21,7 @@
2021
ArtifactBundle,
2122
ArtifactBundleArchive,
2223
DebugIdArtifactBundle,
24+
ProjectArtifactBundle,
2325
ReleaseArtifactBundle,
2426
SourceFileType,
2527
)
@@ -179,11 +181,6 @@ def get(self, request: Request, project: Project, event_id: str) -> Response:
179181
has_uploaded_artifact_bundle_with_release = ReleaseArtifactBundle.objects.filter(
180182
organization_id=project.organization_id, release_name=release.version
181183
).exists()
182-
has_uploaded_some_artifact_with_a_debug_id = DebugIdArtifactBundle.objects.filter(
183-
organization_id=project.organization_id,
184-
artifact_bundle__projectartifactbundle__project_id=project.id,
185-
).exists()
186-
187184
debug_images = get_path(event_data, "debug_meta", "images")
188185
debug_images = debug_images if debug_images is not None else []
189186

@@ -212,6 +209,23 @@ def get(self, request: Request, project: Project, event_id: str) -> Response:
212209
):
213210
debug_ids_with_uploaded_source_map.add(str(debug_id_artifact_bundle.debug_id))
214211

212+
has_uploaded_some_artifact_with_a_debug_id = bool(
213+
debug_ids_with_uploaded_source_file or debug_ids_with_uploaded_source_map
214+
) or (
215+
DebugIdArtifactBundle.objects.filter(
216+
organization_id=project.organization_id,
217+
)
218+
.filter(
219+
Exists(
220+
ProjectArtifactBundle.objects.filter(
221+
artifact_bundle_id=OuterRef("artifact_bundle_id"),
222+
project_id=project.id,
223+
)
224+
)
225+
)
226+
.exists()
227+
)
228+
215229
# Get all abs paths and query for their existence so that we can match release artifacts
216230
release_process_abs_path_data = {}
217231
if release is not None:

0 commit comments

Comments
 (0)