[FIXED] Was ist der Unterschied zwischen select_related und prefetch_related in Django ORM?

Ausgabe

Im Django-Dokument,

select_related()“folgt” Fremdschlüsselbeziehungen und wählt zusätzliche zugehörige Objektdaten aus, wenn es seine Abfrage ausführt.

prefetch_related()führt für jede Beziehung eine separate Suche durch und führt das “Joining” in Python durch.

Was bedeutet es, “die Verbindung in Python zu machen”? Kann das jemand anhand eines Beispiels veranschaulichen?

Mein Verständnis ist, dass für Fremdschlüsselbeziehungen select_related; und für M2M-Beziehungen verwenden Sie prefetch_related. Ist das richtig?

Lösung

Ihr Verständnis ist größtenteils richtig. Sie verwenden, select_relatedwenn das Objekt, das Sie auswählen werden, ein einzelnes Objekt ist, so OneToOneFieldoder eine ForeignKey. Sie verwenden, prefetch_relatedwenn Sie einen “Satz” von Dingen erhalten möchten, also ManyToManyFields, wie Sie es angegeben haben, oder kehren Sie ForeignKeys um. Nur um zu verdeutlichen, was ich mit “umgekehrten ForeignKeys” meine, hier ein Beispiel:

class ModelA(models.Model):
    pass

class ModelB(models.Model):
    a = ForeignKey(ModelA)

ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship

Der Unterschied besteht darin, dass select_relatedein SQL-Join ausgeführt wird und die Ergebnisse daher als Teil der Tabelle vom SQL-Server zurückerhalten werden. prefetch_relatedführt dagegen eine andere Abfrage aus und reduziert damit die redundanten Spalten im Originalobjekt ( ModelAim obigen Beispiel). Sie können prefetch_relatedfür alles verwenden, was Sie verwenden können select_related.

Die Kompromisse bestehen darin prefetch_related, dass eine Liste von IDs erstellt und an den Server zurückgesendet werden muss, was eine Weile dauern kann. Ich bin mir nicht sicher, ob es eine nette Möglichkeit gibt, dies in einer Transaktion zu tun, aber ich verstehe, dass Django immer nur eine Liste sendet und sagt SELECT … WHERE pk IN (…,…,…) Grundsätzlich. In diesem Fall, wenn die vorab abgerufenen Daten spärlich sind (sagen wir, US-Staatsobjekte, die mit den Adressen von Personen verknüpft sind), kann dies sehr gut sein, aber wenn es näher an einer Eins-zu-Eins-Daten ist, kann dies viel Kommunikation verschwenden. Probieren Sie im Zweifelsfall beide aus und sehen Sie, was besser funktioniert.

Alles, was oben besprochen wurde, dreht sich im Wesentlichen um die Kommunikation mit der Datenbank. Auf der Python-Seite hat es jedoch prefetch_relatedden zusätzlichen Vorteil, dass ein einzelnes Objekt verwendet wird, um jedes Objekt in der Datenbank darzustellen. Mit select_relateddoppelten Objekten werden in Python für jedes “übergeordnete” Objekt erstellt. Da Objekte in Python einen ordentlichen Speicheraufwand haben, kann dies auch eine Überlegung sein.


Beantwortet von –
CrazyCasta


Antwort geprüft von –
Timothy Miller (FixError Admin)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like