performance - Doctrine 关系会影响应用程序的性能吗?
问题描述
我正在与一个新团队合作一个 Symfony 项目,由于性能问题,他们决定尽可能停止使用 Doctrine 关系。
例如,我必须存储我的“关系”的 ID,而不是使用 ManyToOne 关系。
但我想知道这是否是一个真正的问题?
问题是,它改变了检索信息等的编码方式。
解决方案
性能问题很可能来自查询未优化的事实。
如果您让 Doctrine(处理查询的 Symfony 组件)自己执行查询(通过使用findBy()
, findAll()
,findOneBy()
等),它将首先获取您所询问的内容,然后执行更多查询,因为它需要来自其他表的数据。
让我们举个最常见的例子,图书馆。
Entities
- 书
- 作者
- 架子
Relations
- 一个
Book
有一个Author
,但一个Author
可以有很多Books
(Book <= ManyToOne => Author
) - 一个
Book
存储在一个Shelf
(Book <= OneToOne => Sheilf
)
现在,如果您查询 a Book
,Doctrine 也将获取Shelf
它,因为它是一个OneToOne
关系。
但它不会 fetch Author
。在您的反对中,您只能访问,book.author.id
因为此信息Book
本身就存在。
因此,如果在您的 Twig 视图中,您执行类似的操作{{ 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 查询以避免过多的额外查询。
最后,我会说顺序很重要。使用ORDER BY
在子节点之前获取父节点也将大大减少 Doctrine 自己可能执行的查询数量。
[边注]
您还可以更改实体注释上的 fetch 方法以“优化” Doctrine 预制查询。
fetch="EXTRA_LAZY
fetch="LAZY
fetch="EAGER
但它并不聪明,而且通常不能真正提供我们真正需要的东西。
因此,自定义查询是最佳选择。
推荐阅读
- c - 在 C 中运行 Valgrind 时,我收到大小为 8 的无效读取
- google-chrome-extension - chrome 扩展程序可以截取它自己的弹出窗口吗?
- makefile - 在linux内核源码中,为什么arch/arm64只有一个defconfig文件?(对于 arch/arm 有很多 xxx_defconfig 文件)
- python - 高效处理 pandas 组
- php - PHP会话读取错误值
- python - 我的文本游戏 python 脚本无法正确执行 if/else 函数
- python - 传递 df 时带有 OneHotEncoder 问题的列转换器
- reactjs - 如何使 Material UI AutoComplete 组件看起来像 Material UI 网站上的组件
- node.js - Axios 发布请求提供参考错误
- javascript - 我应该如何删除 d3-force 中的节点?