Ich habe eine Car
-Einheit mit einer Viele-zu-Eins-Beziehung mit einer Entität Owner
. Wenn ich alle Autos auswähle, führt Doctrine eine Abfrage in der Tabelle Car
und anschließend eine Abfrage in der Tabelle Owner
für jedes Auto durch . So wird das Holen von N Autos zu N + 1 Anfragen anstelle einer einzelnen JOIN Abfrage zwischen den Tabellen Car
und Owner
.
Meine Entitäten sind wie folgt:
%Vor%Wenn ich die Autos mit ihren Besitzern auflisten möchte, mache ich:
%Vor%Nun, das alles funktioniert sehr gut, abgesehen von der Tatsache, dass Doctrine für jedes Auto eine Abfrage ausgibt.
%Vor%Natürlich möchte ich, dass mein Abfrageprotokoll so aussieht:
%Vor% Ob ich fetch="EAGER"
oder fetch="LAZY"
habe, spielt keine Rolle, und selbst wenn ich eine benutzerdefinierte DQL-Abfrage mit JOIN zwischen den beiden Entitäten anlege, bewirkt $car->getOwner()
immer noch, dass Doctrine die Datenbank abfragt (außer ich benutze EAGER). In diesem Fall verursacht $repo->findAll()
alle von ihnen).
Bin ich hier einfach zu müde, und so soll es funktionieren - oder gibt es eine kluge Möglichkeit, Doctrine dazu zu zwingen, stattdessen die JOIN-Abfrage durchzuführen?
Zumindest in 1.x Doctrine, wenn Sie nach verwandten Objekten suchen wollten, mussten Sie DQL verwenden. In Ihrem Fall würde die DQL-Abfrage etwa so aussehen:
%Vor% Führen Sie zuerst eine DQL-Abfrage aus, bei der Sie alle verbundenen Fahrzeuge (DQL JOIN) mit dem Eigentümer auswählen. Setzen Sie den Besitzer in select()
.
Doctrine 2 führt dann einen JOIN durch (normalerweise schneller, da weniger Datenbankabfragen abhängig von der Anzahl der Datensätze benötigt werden).
Starten Sie nun Ihre foreach
, Doctrine findet die Entitäten intern und es werden keine einzelnen Abfragen ausgeführt, wenn Sie owner
benötigen.
Überwachen Sie die Anzahl der Abfragen zuerst / nach jeder Änderung (zB mysql general log)
Ihre Frage ...
%Vor%... befindet sich in einer foreach-Schleife, daher wird die Abfrage sicher mehrmals ausgegeben.
Wenn Sie benutzerdefinierten DQL schreiben, um damit umzugehen, sollte $car->getOwner()
überhaupt nicht in diesem Feature enthalten sein. Dies ist eine Funktion der Fahrzeugklasse. Die benutzerdefinierte DQL, die Sie schreiben würden, würde die exakte SQL-Abfrage, auf die Sie hinweisen, nachahmen und Ihren Beitritt effizient erledigen.