Django: m2m's .count() и .order_by() с аннотированными значениями работают очень медленно
Видео содержит около 300k данных и около 2k тегов.
Если вы сделаете .annotate(count=Count('video'))
и затем сделаете .order_by('-count')
с таким значением, как показано ниже, это займет
Это займет около 500 мс.
Кроме того, поскольку мы используем пагинацию DRF, .count()
выполняется за кулисами, и скорость .count()
составляет около 500 мс.
Я понятия не имею, что вызывает эти вещи, хотя я исследовал их. Как я могу это исправить?
# models.py
class Tag(models.Model):
name = models.CharField(unique=True, max_length=100)
is_actress = models.BooleanField(default=False, db_index=True)
created_at = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ["-is_actress"]
def __str__(self):
return self.name
class Video(models.Model):
tags = models.ManyToManyField(Tag, blank=True, db_index=True)
# serializers.py
class TagSerializer(serializers.ModelSerializer):
count = serializers.IntegerField()
class Meta:
model = Tag
fields = ("pk", "name", "is_actress", "count")
# views.py
class TagListPagination(PageNumberPagination):
page_size = 100
class TagListView(generics.ListAPIView):
serializer_class = TagSerializer
pagination_class = TagListPagination
def get_queryset(self):
return Tag.objects.annotate(count=Count("video")).order_by("-count")