Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Doctrine2 in Symfony2:Wie kann ich sehen, welcher Objektaufruf zu einer Abfrage führt?

Doctrine verwendet die Identity Map Muster zum Verfolgen von Objekten. Wann immer Sie also ein Objekt aus der Datenbank abrufen, behält Doctrine eine Referenz auf dieses Objekt in seiner UnitOfWork. Und im Grunde verwendet es die ID als Schlüssel zum Verwalten von Objekten innerhalb seiner UnitOfWork.

Z. B.

$objectA = $this->entityManager->find('EntityName', 1);
$objectB = $this->entityManager->find('EntityName', 1);

würde nur eine SELECT-Abfrage für die Datenbank auslösen. In der zweiten Aufrufdoktrin wird die Identitätskarte überprüft und würde die gleiche ID finden, ohne einen Datenbank-Roundtrip durchzuführen. Selbst wenn Sie ein Proxy-Objekt verwenden, hätte das Objekt dieselbe ID.

Aber für

$objectA = $repository->findOneBy(array('name' => 'Benjamin'));
$objectB = $repository->findOneBy(array('name' => 'Benjamin'));

Sie würden zwei Abfragen in Ihrem SQL-Protokoll sehen, obwohl Sie auf dasselbe Objekt verweisen. Lehre kennt Objekte nur anhand ihrer ID , daher muss eine Abfrage nach einem anderen Kriterium an die Datenbank gehen, auch wenn sie zuvor ausgeführt wurde.

Aber Doktrin ist schlau, sie erstellt keine neue Entität, sondern holt sich die ID und schaut, ob sie schon im Speicher ist.

PHP folgt dem Copy-on-Write-Paradigma, es ist ein Optimierungsprinzip. Eine echte Kopie einer Variablen wird nur dann erstellt, wenn die Variable geändert wird. Die Speichernutzung für eine Anfrage, die Objekte aus der Datenbank liest, ist also die gleiche, als würde man keine Variablenkopie behalten.

Nur wenn Sie also Variablen ändern, erstellen Ihre Anwendungen intern neue Variablen und verbrauchen Speicher.

Wenn Sie also flush callen , durchläuft die Doktrin die Identitätskarte und vergleicht die ursprüngliche Eigenschaft jedes Objekts mit den aktuellen Werten. Wenn Änderungen erkannt werden, wird es für eine UPDATE-Abfrage in die Warteschlange gestellt. Nur tatsächlich aktualisierte Felder werden in der Datenbank geändert.

Optimieren

Daher ist es manchmal sinnvoll, Objekte als schreibgeschützt zu markieren (nur Einfügen und Entfernen), damit sie nicht im Änderungssatz enthalten sind (Sie können dies in Ihrer XML-Zuordnungsdatei oder mit Anmerkungen oder in Ihrem PHP-Code tun).

$entityManager->getUnitOfWork()->markReadOnly($entity)

Oder leeren Sie nur eine Entität

$entityManager->flush($entity)