sql >> データベース >  >> RDS >> Mysql

Symfony2のDoctrine2:どのオブジェクト呼び出しがクエリにつながるかをどうやって見ることができますか?

    Doctrineはアイデンティティマップを使用します オブジェクトを追跡するためのパターン。したがって、データベースからオブジェクトをフェッチするときはいつでも、DoctrineはそのUnitOfWork内にこのオブジェクトへの参照を保持します。そして基本的には、UnitOfWork内のオブジェクトを管理するためのキーとしてIDを使用します。

    例:

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

    データベースに対して1つのSELECTクエリのみを実行します。 2番目の呼び出しでは、DoctrineはIDマップをチェックし、データベースのラウンドトリップを実行せずに同じIDを見つけます。プロキシオブジェクトを使用する場合でも、オブジェクトは同じIDを持ちます。

    しかし

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

    同じオブジェクトを参照しているにもかかわらず、SQLログに2つのクエリが表示されます。 DoctrineはIDでのみオブジェクトを認識します 、したがって、以前に実行された場合でも、別の条件のクエリはデータベースに送信する必要があります。

    しかし、教義は賢く、新しいエンティティを作成するのではなく、IDを取得し、それがメモリ内で正常であるかどうかを確認します。

    PHPは、コピーオンライトのパラダイムに従います。これは最適化の原則です。変数の実際のコピーは、変数が変更された場合にのみ作成されます。したがって、データベースからオブジェクトを読み取るリクエストのメモリ使用量は、変数のコピーを保持しない場合と同じです。

    したがって、変数を変更した場合にのみ、アプリケーションは内部で新しい変数を作成し、メモリを消費します。

    したがって、フラッシュを呼び出すと 、doctrineはIdentiy Mapを反復処理し、各obecjtsの元のプロパティを現在の値と比較します。変更が検出されると、UPDATEクエリのキューに入れられます。データベースでは、実際に更新されたフィールドのみが変更されます。

    最適化する方法

    そのため、オブジェクトを読み取り専用(挿入と削除のみ)としてマークすることが理にかなっている場合があります。これにより、オブジェクトはチェンジセットに含まれなくなります(xmlマッピングファイル、注釈、またはphpコードで行うことができます)。

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

    または、1つのエンティティのみをフラッシュします

    $entityManager->flush($entity)
    



    1. 複数のレールモデルからフィードを効率的に作成しますか?

    2. ストップワードリストが空であってもストップワードが含まれている場合、全文検索は機能しません

    3. MSSQL正規表現

    4. MySQLで行の値を列として表示する方法