Browse Source

perf: Remove huge EventUser query from GroupTagValueSerializer (#6195)

GroupTagValueSerializer used to fetch *all* EventUser records for a
project (which could have been millions -- the reason we're making this
change is because it showed up in the top slowest query logs).

The values were used to build a lookup dict to retrieve the proper
'label'. It turns out the label is simply the raw value without the
prefix. (e.g. Tag Value: "id:10", Label: "10") So instead of doing the
query and building the dict, we just strip the prefix if one exists.

This should be functionally equivalent but without doing the query.
Brett Hoerner 7 years ago
parent
commit
ffb686f563

+ 17 - 16
src/sentry/api/serializers/models/grouptagvalue.py

@@ -7,7 +7,7 @@ from django.db.models import Q
 from six.moves import reduce
 
 from sentry.api.serializers import Serializer, register
-from sentry.models import EventUser, GroupTagValue, TagKey, TagValue
+from sentry.models import GroupTagValue, TagKey, TagValue
 
 
 def parse_user_tag(value):
@@ -38,17 +38,6 @@ class GroupTagValueSerializer(Serializer):
                 continue
 
         tag_labels = {}
-        if user_lookups:
-            tag_labels.update(
-                {
-                    ('sentry:user', euser.tag_value): euser.get_label()
-                    for euser in EventUser.objects.filter(
-                        reduce(operator.or_, user_lookups),
-                        project_id=project_id,
-                    )
-                }
-            )
-
         other_lookups = [Q(key=i.key, value=i.value) for i in item_list if i.key != 'sentry:user']
         if other_lookups:
             tag_labels.update(
@@ -63,10 +52,22 @@ class GroupTagValueSerializer(Serializer):
 
         result = {}
         for item in item_list:
-            try:
-                label = tag_labels[(item.key, item.value)]
-            except KeyError:
-                label = item.value
+            if item.key == 'sentry:user':
+                if item.value.startswith('id:'):
+                    label = item.value[len('id:'):]
+                elif item.value.startswith('email:'):
+                    label = item.value[len('email:'):]
+                elif item.value.startswith('username:'):
+                    label = item.value[len('username:'):]
+                elif item.value.startswith('ip:'):
+                    label = item.value[len('ip:'):]
+                else:
+                    label = item.value
+            else:
+                try:
+                    label = tag_labels[(item.key, item.value)]
+                except KeyError:
+                    label = item.value
             result[item] = {
                 'name': label,
             }

+ 0 - 16
tests/sentry/api/serializers/test_grouptagvalue.py

@@ -34,19 +34,3 @@ class GroupTagValueSerializerTest(TestCase):
         assert result['key'] == 'user'
         assert result['value'] == grouptagvalue.value
         assert result['name'] == euser.get_label()
-
-    def test_with_no_tagvalue(self):
-        user = self.create_user()
-        project = self.create_project()
-        grouptagvalue = GroupTagValue.objects.create(
-            project_id=project.id,
-            group_id=self.create_group(project=project).id,
-            key='sentry:user',
-            value='email:foo@example.com',
-        )
-
-        result = serialize(grouptagvalue, user)
-        assert result['id'] == six.text_type(grouptagvalue.id)
-        assert result['key'] == 'user'
-        assert result['value'] == grouptagvalue.value
-        assert result['name'] == grouptagvalue.value