Mysql
 sql >> Database >  >> RDS >> Mysql

Doctrine2 in Symfony2:Come posso vedere quale chiamata oggetto conduce in una query?

Doctrine utilizza la Mappa dell'identità modello per tracciare gli oggetti. Quindi, ogni volta che si recupera un oggetto dal database, Doctrine conserva un riferimento a questo oggetto all'interno del suo UnitOfWork. E fondamentalmente usa l'ID come chiave per gestire gli oggetti all'interno del suo UnitOfWork.

Es.

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

lancerebbe solo una query SELECT sul database. Nella seconda chiamata la dottrina controllerà la mappa dell'identità e troverebbe lo stesso ID senza fare un roundtrip del database. Anche se utilizzi un oggetto proxy, l'oggetto avrà lo stesso ID.

Ma per

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

vedresti due query nel tuo registro SQL, nonostante tu faccia riferimento allo stesso oggetto. Dottrine conosce gli oggetti solo per ID , quindi una query per un criterio diverso deve andare al database, anche se è stata eseguita in precedenza.

Ma la dottrina è intelligente, non crea una nuova entità ma ottiene l'ID e cerca se è già in memoria.

PHP segue il paradigma copy-on-write, è un principio di ottimizzazione. Una copia reale di una variabile viene eseguita solo quando la variabile viene modificata. Quindi l'utilizzo della memoria per una richiesta che legge oggetti dal database è lo stesso che se non si conservasse una copia variabile.

Quindi, solo quando modifichi le variabili, le tue applicazioni creano nuove variabili internamente e consumano memoria.

Quindi, quando chiami colore , la dottrina esegue un'iterazione sulla mappa dell'identità e confronta la proprietà originale di ciascun oggetto con i valori correnti. Se vengono rilevate modifiche, si accoderà per una query UPDATE. Solo i campi effettivamente aggiornati vengono modificati nel database.

Come ottimizzare

Quindi a volte ha senso contrassegnare gli oggetti come di sola lettura (solo inserimento e rimozione), quindi non saranno nel changeset (puoi farlo nel tuo file di mappatura xml o con annotazioni o nel tuo codice php).

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

Oppure svuota solo un'entità

$entityManager->flush($entity)