-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(group_model): optimize group.filter_to_team query to not do a full table scan #88393
Conversation
Fixes SENTRY-2HWB |
should also fix SENTRY-3JZW |
src/sentry/models/group.py
Outdated
Q(team=team) | Q(user_id__in=user_ids) | ||
).values_list("group_id", flat=True) | ||
|
||
assigned_groups = GroupAssignee.objects.filter(team=team).values_list( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think if you do
assigned_groups = (
GroupAssignee.objects.filter(team=team) |
GroupAssignee.objects.filter(user_id__in=user_ids)
).values_list("group_id", flat=True)
it can do it in one query instead of two?
src/sentry/models/group.py
Outdated
assigned_groups = ( | ||
GroupAssignee.objects.filter(team=team) | ||
| GroupAssignee.objects.filter(user_id__in=user_ids) | ||
).values_list("group_id", flat=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
print((GroupAssignee.objects.filter(user_id__in=[2,3,4]) | GroupAssignee.objects.filter(team_id=1)).values_list("group_id", flat=True).query)
produces:
SELECT "sentry_groupasignee"."group_id"
FROM "sentry_groupasignee"
WHERE ("sentry_groupasignee"."team_id" = 1 OR "sentry_groupasignee"."user_id" IN (2, 3, 4))`
Which is the same query as before, I think?
The problem you're trying to avoid is the OR I think, since it's breaking index usage? You probably want a union
print(GroupAssignee.objects.filter(user_id__in=[2,3,4]).union(GroupAssignee.objects.filter(team_id=1)).values_list("group_id", flat=True).query)
produces
(
SELECT "sentry_groupasignee"."group_id" AS "col1"
FROM "sentry_groupasignee"
WHERE "sentry_groupasignee"."user_id" IN (2, 3, 4)
)
UNION
(
SELECT "sentry_groupasignee"."group_id" AS "col1"
FROM "sentry_groupasignee"
WHERE "sentry_groupasignee"."team_id" = 1
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, i thought .union
and |
were equivalent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs reference: https://docs.djangoproject.com/en/5.1/ref/models/querysets/#or, |
operator does an OR
…88584) fixes SENTRY-2HWB fixes SENTRY-3JZW Parallel change to #88393, but for the GroupHistory model.
…l table scan (#88393) Fixes SENTRY-2HWB Optimizes the group manager's filter_to_team query to not do a full table scan on the GroupAssignee table. It seems like Postgres was unable to use a combination of the team and user indexes when filtering for teams and users, and instead used the Group index, which caused a full table scan. --------- Co-authored-by: Josh Ferge <[email protected]>
…88584) fixes SENTRY-2HWB fixes SENTRY-3JZW Parallel change to #88393, but for the GroupHistory model.
Fixes SENTRY-2HWB
Optimizes the group manager's filter_to_team query to not do a full table scan on the GroupAssignee table.
It seems like Postgres was unable to use a combination of the team and user indexes when filtering for teams and users, and instead used the Group index, which caused a full table scan.