ich zwei verwandte Modelle, die wie unten aussieht:Django ORM - MySQL Query-Optimierung Zahl für verwandte Modelle
class Enterprise(models.Model):
id = models.AutoField(primary_key=True)
subsystem_id = models.IntegerField()
name = models.CharField(max_length=255, unique=True)
modif_date = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Project(models.Model):
id = models.AutoField(primary_key=True)
subsystem_id = models.IntegerField()
name = models.CharField(max_length=255)
modif_date = models.DateTimeField(auto_now=True)
enterprise = models.ForeignKey('Enterprise'
on_delete = CASCADE)
active = models.BooleanField(default=True)
Aus meiner Sicht müssen alle aktiven Unternehmen zu erhalten und sie aufzulisten. Ich mache es so:
enterprise_list = Enterprise.objects.annotate(project_count=Count('project')).filter(
Q(active=True) | Q(subsystem_id=-1), project_count__gt=0
)
serializer = EnterpriseSerializer(enterprise_list, many=True)
Dann meine Serializer Projektliste mit einigen zusätzlichen Abfrage angezeigt wird:
class EnterpriseSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
name = serializers.CharField(max_length=255, required=False)
project_list = serializers.SerializerMethodField()
def get_project_list(self, enterprise):
project_list = Project.objects.filter(Q(active=True) | Q(subsystem_id=-1),
enterprise=enterprise)
serializer = ProjectSerializer(project_list, many=True)
return serializer.data
class Meta:
model = Enterprise
fields = ('id', 'name', 'project_list')
Dieser Code funktioniert gut, aber es hat sehr ernstes Thema - Leistung. Die erste Abfrage für Enterprise gibt eine Liste von ~ 1500 Objekten zurück. Dann führt der Serializer für jedes Objekt eine einzelne Abfrage aus, um zusätzliche Daten für das Projekt abzurufen, was zu ~ 1500 Abfragen führt.
Ich habe versucht prefetch_related
und select_related
aber entweder mache ich etwas falsch oder es funktioniert nicht in meinem Fall.
In der anderen Hand kann ich zuerst eine Liste des Projekts bekommen. Dies könnte meine Zählannotation eliminieren. Aber ich sollte sie nach Unternehmen gruppieren, aber soweit ich weiß, unterstützt Django ORM für MySQL solche Operationen nicht. Ich denke nicht, analysieren die Daten in Python und übergeben sie an Serialisierer als ein Diktat ist eine gute Idee.
Können Sie mir ein paar Tipps geben, wie Sie die Abfragen in meinem Fall einschränken können? Vielleicht wird prefetch/select_related
in meinem Fall hilfreich sein, aber wie man sie hier richtig einsetzt? Ich benutze MySQL-Datenbank.
Oh, also habe ich verwendet, völlig falsch prefetch_related. Danke fürs klarstellen. – Djent