sql >> Databáze >  >> RDS >> Mysql

Doctrine2 v Symfony2:Jak mohu zjistit, které volání objektu vede k dotazu?

Doctrine používá Mapu identity vzor pro sledování objektů. Takže kdykoli načtete objekt z databáze, Doctrine uchová odkaz na tento objekt ve své UnitOfWork. A v podstatě používá ID jako klíč ke správě objektů v UnitOfWork.

Např.

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

by vyvolal pouze jeden dotaz SELECT proti databázi. Ve druhém volání doktrína zkontroluje mapu identity a najde stejné ID, aniž by provedla zpáteční cestu databáze. I když použijete objekt proxy, objekt bude mít stejné ID.

Ale pro

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

v protokolu SQL byste viděli dva dotazy, a to navzdory skutečnosti, že odkazujete na stejný objekt. Doktrína zná objekty pouze podle ID , takže dotaz na jiná kritéria musí jít do databáze, i když byl dříve proveden.

Ale doktrína je chytrá, nevytváří novou entitu, ale získává ID a hledá, jestli už je v paměti.

PHP se řídí paradigmatem copy-on-write, je to princip optimalizace. Skutečná kopie proměnné se vytvoří pouze tehdy, když je proměnná upravena. Využití paměti pro požadavek, který čte objekty z databáze, je tedy stejné, jako kdyby se neuchovávala kopie proměnné.

Takže pouze když změníte proměnné, vaše aplikace vytvoří nové proměnné interně a spotřebovávají paměť.

Takže když zavoláte flush , doktrína iteruje přes Identiy Map a porovnává původní vlastnost každého obecjta s aktuálními hodnotami. Pokud jsou zjištěny změny, zařadí se do fronty na dotaz UPDATE. V databázi se mění pouze aktuálně aktualizovaná pole.

Jak optimalizovat

Někdy má tedy smysl označit objekty jako pouze pro čtení (pouze vložit a odebrat), takže nebudou v changesetu (můžete to udělat ve vašem xml mapovacím souboru nebo pomocí anotací nebo ve vašem php kódu).

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

Nebo vyprázdněte pouze jednu entitu

$entityManager->flush($entity)



  1. Pomalý dotaz při použití ORDER BY

  2. TDS Server – Použití příkazů Transact-SQL (T-SQL) pro práci s daty Salesforce na SQL Server

  3. Připojení Genero k SQL Serveru

  4. Jaký je ekvivalent SQL Server APPLY v Oracle?