Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Doctrine2 w Symfony2:Jak mogę zobaczyć, które wywołanie obiektu prowadzi do zapytania?

Doctrine korzysta z Mapy tożsamości wzór do śledzenia obiektów. Tak więc za każdym razem, gdy pobierasz obiekt z bazy danych, Doctrine przechowuje odniesienie do tego obiektu w swojej UnitOfWork. I zasadniczo używa identyfikatora jako klucza do zarządzania obiektami wewnątrz swojego UnitOfWork.

Np.

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

uruchomiłoby tylko jedno zapytanie SELECT w bazie danych. W drugim wywołaniu doktryna sprawdzi mapę tożsamości i znajdzie ten sam identyfikator bez wykonywania objazdu bazy danych. Nawet jeśli użyjesz obiektu proxy, obiekt będzie miał ten sam identyfikator.

Ale dla

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

w dzienniku SQL zobaczysz dwa zapytania, mimo że odwołujesz się do tego samego obiektu. Doctrine zna obiekty tylko według identyfikatora , więc zapytanie o inne kryteria musi trafić do bazy danych, nawet jeśli zostało wcześniej wykonane.

Ale doktryna jest sprytna, nie tworzy nowego bytu, ale otrzymuje identyfikator i sprawdza, czy jest już w pamięci.

PHP postępuje zgodnie z paradygmatem copy-on-write, jest to zasada optymalizacji. Prawdziwa kopia zmiennej jest tworzona tylko wtedy, gdy zmienna jest modyfikowana. Tak więc użycie pamięci dla żądania, które odczytuje obiekty z bazy danych, jest takie samo, jak gdyby nie przechowywać kopii zmiennej.

Tak więc tylko wtedy, gdy zmieniasz zmienne, aplikacje tworzą wewnętrznie nowe zmienne i zużywają pamięć.

Więc kiedy zadzwonisz flush , doktryna iteruje po Mapie Tożsamości i porównuje oryginalną właściwość każdego obecjts z bieżącymi wartościami. W przypadku wykrycia zmian zostanie on umieszczony w kolejce na zapytanie UPDATE. Tylko aktualnie zaktualizowane pola są zmieniane w bazie danych.

Jak zoptymalizować

Czasami więc ma sens oznaczenie obiektów jako tylko do odczytu (tylko wstawianie i usuwanie), aby nie znajdowały się w zestawie zmian (możesz to zrobić w swoim pliku mapowania xml lub z adnotacjami lub w kodzie php).

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

Lub opróżnij tylko jedną jednostkę

$entityManager->flush($entity)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Automatyczne wypełnianie kraju i miasta z kodu pocztowego i odwrotnie

  2. Jak wyodrębnić podciąg w MySQL

  3. mysql przecinają się

  4. Awaria MySQL podczas uruchamiania

  5. mysql:group by ID, uzyskaj najwyższy priorytet dla każdego ID