Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Doctrine2 trong Symfony2:Làm cách nào để biết đối tượng gọi nào dẫn đến một truy vấn?

Doctrine sử dụng Bản đồ nhận dạng mẫu để theo dõi các đối tượng. Vì vậy, bất cứ khi nào bạn tìm nạp một đối tượng từ cơ sở dữ liệu, Doctrine sẽ giữ một tham chiếu đến đối tượng này bên trong UnitOfWork của nó. Và về cơ bản, nó sử dụng ID làm khóa để quản lý các đối tượng bên trong UnitOfWork của nó.

Ví dụ:

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

sẽ chỉ kích hoạt một truy vấn SELECT đối với cơ sở dữ liệu. Trong học thuyết cuộc gọi thứ hai sẽ kiểm tra bản đồ nhận dạng và sẽ tìm thấy cùng một ID mà không cần thực hiện một vòng cơ sở dữ liệu. Ngay cả khi bạn sử dụng đối tượng proxy, đối tượng sẽ có cùng một ID.

Nhưng đối với

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

bạn sẽ thấy hai truy vấn trong nhật ký SQL của mình, mặc dù thực tế là bạn tham chiếu cùng một đối tượng. Doctrine chỉ biết các đối tượng theo ID , do đó, một truy vấn cho một tiêu chí khác phải đi đến cơ sở dữ liệu, ngay cả khi nó đã được thực thi trước đó.

Nhưng học thuyết rất thông minh, nó không tạo ra một thực thể mới mà lấy ID và xem nó có giống trong bộ nhớ không.

PHP tuân theo mô hình copy-on-write, đó là một nguyên tắc tối ưu hóa. Bản sao thực của một biến chỉ được tạo ra khi biến đó được sửa đổi. Vì vậy, việc sử dụng bộ nhớ cho một yêu cầu đọc các đối tượng từ cơ sở dữ liệu cũng giống như nếu không giữ một bản sao biến.

Vì vậy, chỉ khi bạn thay đổi các biến, ứng dụng của bạn mới tạo ra các biến mới trong nội bộ và sử dụng bộ nhớ.

Vì vậy, khi bạn gọi flush , học thuyết lặp qua Bản đồ định danh và so sánh từng thuộc tính ban đầu của obecjts với các giá trị hiện tại. Nếu các thay đổi được phát hiện, nó sẽ xếp hàng cho một truy vấn CẬP NHẬT. Chỉ các trường được cập nhật thực sự mới được thay đổi trong cơ sở dữ liệu.

Cách tối ưu hóa

Vì vậy, đôi khi sẽ hợp lý khi đánh dấu các đối tượng là chỉ đọc (chỉ chèn và xóa), do đó chúng sẽ không nằm trong tập thay đổi (bạn có thể làm điều đó trong tệp ánh xạ xml hoặc với chú thích hoặc trong mã php của bạn).

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

Hoặc chỉ xóa một thực thể

$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. Gán xml được tạo bởi vòng lặp while cho một biến

  2. Nhận ID bảng sau khi chèn với ColdFusion và MySQL

  3. Tuyên bố PDO của tôi không hoạt động

  4. python mysqldb err trên máy Mac của tôi:Thư viện không được tải:@ rpath / libmysqlclient.21.dylib

  5. SQLSTATE [HY000] [1698] Quyền truy cập bị từ chối đối với người dùng 'root' @ 'localhost'