[我正在与一个新团队一起进行Symfony项目,由于性能问题,他们决定尽最大可能停止使用教义关系。
例如,我必须存储我的“关系”的ID而不是使用ManyToOne关系。
但是我想知道这是否是一个真正的问题?
事实是,它改变了检索信息的编码方式等。
findBy()
,findAll()
,findOneBy()
等),它将首先获取您要查询的内容,然后再执行更多查询将需要其他表中的数据。让我们举一个最常见的例子,一个库。
实体
书关系
Book
有一个Author
,但是一个Author
可以有许多Books
(Book <= ManyToOne => Author
)Book
存储在一个Shelf
(Book <= OneToOne => Sheilf
)中]Book
,则Doctrine也将获取Shelf
,因为它是OneToOne
关系。但它不会获取Author
。在您的对象中,您只能访问book.author.id
,因为此信息位于Book
本身中。{{ book.author.name }}
之类的操作,因为在初始查询中未获取信息,Doctrine将添加一个额外的查询以获取有关该书作者的数据。因此,为避免这种情况,您必须自定义查询,这样它可以一次性获得所需的数据,如下所示:
public function getBookFullData(Book $book) {
$qb=$this->createQueryBuilder('book');
$qb->addSelect('shelf')
->addSelect('author')
->join('book.shelf', 'shelf')
->join('book.author', 'author');
return $qb->getQuery()->getResult();
}
通过此自定义查询,您可以一次性获得一本书的所有数据,因此,Doctrine不必进行额外的查询。
因此,尽管示例非常简单,但我相信您可以理解,在大型项目中,免费使用教义将只会增加额外查询的数量。我的一个项目,在优化之前,每页加载达到1500个查询...另一方面,忽略数据库中的关系不是很好。实际上,使用外键和索引比没有外键和索引的数据库要快。
如果您希望您的应用程序尽快运行,则必须使用关系来优化数据库查询速度,并优化Doctrine查询以避免不必要的额外查询次数。
[旁注]
您还可以更改实体注释上的访存方法,以“优化” Doctrine预制查询。
fetch="EXTRA_LAZY
fetch="LAZY
fetch="EAGER