2017-06-28 5 views
0

私はSymfonyアプリケーションを作成していますが、Doctrineエンティティの熱心な読み込みに問題があります。 パフォーマンスを維持しながら、同じエンティティインスタンスの複数のコレクションを複数のコレクションにロードできるかどうかはわかりません。Doctrineでエンティティの複数のコレクションを展開する

人々は1つのエンティティとその関係の1つを読み込むインターネット上に多くの例があります。 例:実際には私も記事のコメントをロードする場合

$user = $em->createQuery(' 
    select a, au 
    from OctiviTestBundle:Article a 
    left join a.authorList au 
    where a.id = ?1') 
    ->setParameter(1, $id) 
    ->getOneOrNullResult(); 

ただし、以下の要求があまりにも多くの結果を取得する(NB著者* NBコメント)=>コンビナトリー爆発

$user = $em->createQuery(' 
    select a, au 
    from OctiviTestBundle:Article a 
    left join a.authorList au 
    left join a.commentList c 
    where a.id = ?1') 
    ->setParameter(1, $id) 
    ->getOneOrNullResult(); 

、Iオブジェクトがデータベースからロードされた後でオブジェクトを再利用する方法が見つけられませんでした。後でもっと多くの部分をロードするために2番目のクエリを作成する方法はわかりません。 例:

$user = $em->createQuery(' 
    select a, au 
    from OctiviTestBundle:Article a 
    left join a.authorList au 
    where a.id = ?1') 
    ->setParameter(1, $id) 
    ->getOneOrNullResult(); 
    $em->LoadRelation($user, 'commentList'); 
    $em->LoadRelation($user, 'commentList.author') 
    $em->LoadRelation($user, 'commentList.author.school'); 
    ... load any relation I want, while keeping only one root object. 

私はメインのエンティティのインスタンス変数、熱心な負荷の2体の関係を持った後、階層を通過できるようにしたいと思います。 私は別のphp変数で2つのリストを読み込むことができますが、 "$ user"変数をビューテンプレートに渡したいだけです。

この問題の解決方法に関するアイデアはありますか? おかげ

私が見つけた唯一の(トリッキー)ソリューションは、このウェブサイト上にある

:()関連企業

$companies = array_map(function($employee) { 
    return $employee->getCompany(); 
}, $employees); 
$repository = $entityManager->getRepository('Acme\Company'); 
$repository->findBy(['id' => $companies]); 
ロード結果を使用しないでください) https://tideways.io/profiler/blog/5-doctrine-orm-performance-traps-you-should-avoid

1 $ companies変数を削除します)。しかし、Doctrineは結果をキャッシュに入れました。したがって、$ employee-> getCompany() - > getName()を実行すると、新しいクエリが生成されません。

=>動作しません:Doctrineは後で再利用するために結果をキャッシュに入れません。

答えて

0

where'sandsを入れても結果が大量になる場合は、結果に対して書き込み操作を行う意思がない場合は、デフォルトのオブジェクトではなく配列としてフェッチする必要があります。

結果のアレイはまだ小枝の中で全く同じように使用されますが、オブジェクトを水和する必要がなくなり、メモリ節約量が膨大になります。

+0

結果は20人の著者+ 20コメント(40行)で、20人のautor * 20コメント(400行)ではありません。 あなたは正しいです。配列を使用すると、すべてのものを1つのユーザー配列で参照して参照することができます。 – Kiruahxh

+0

しかし、私はユーザーオブジェクトを使用するビジネスロジックも持っていますので、オブジェクトを水和することをお勧めします – Kiruahxh

+0

40行だけでも400行でも実際のパフォーマンス上の問題は見られません。私の頭の中で私は1000年代を考えていました。 Sql - > getSQL()を印刷してMySQLで手動でクエリを実行するだけで、Sqlやオブジェクトの水分があなたを殺しているかどうかを調べる価値があります。たぶん、あなたのインデックスはちょっと離れているかもしれません。 – Doug

関連する問題