はじめまして。4月からオトバンクで働き始めました @kalibora と申します。よろしくお願いします。
さて、オトバンクでは Symfony2 を使っており、ORマッパーにはデフォルトの Doctrine2 を使用しているのですが、 そんな中で私が得た知見をいくつか紹介したいと思います。
Fetch mode の話
Doctrine2 には fetch mode という概念があります。
Annotations Reference - Doctrine Object Relational Mapper (ORM) を見ますと Doctrine2には下記の fetch mode があるようです。
fetch mode | 定義できる場所 |
---|---|
EAGER |
@ManyToOne @ManyToMany @OneToOne @OneToMany |
LAZY |
@ManyToOne @ManyToMany @OneToOne @OneToMany |
EXTRA_LAZY |
@ManyToMany @OneToMany |
この fetch mode は、あるエンティティをリポジトリから取得した際に、 関連するエンティティも同時に取得するかどうか?という挙動に関わってくるものです。
ちなみに何も明示的に定義しないと、デフォルトは LAZY
な挙動になります。
すなわち、関連エンティティは取得しません。関連エンティティが必要になった時に自動でデータベースにクエリが走り、取得されます。
使わない(参照されない)関連エンティティも毎回取得してしまうと無駄なので、これは理にかなった挙動だと思います。
ところが、LAZY
だけを使っていると、いわゆる n+1 問題と呼ばれる問題に直面します。