大牛 / n-plus-one-detector
用于检测由 doctrine orm 触发的 n+1 查询的工具
Requires
- php: ^7.1
- doctrine/orm: dev-2.7-initializer-events
Requires (Dev)
- phpunit/phpunit: ^9.2.5
- psalm/plugin-phpunit: ^0.10.1
- squizlabs/php_codesniffer: ^3.5.5
- vimeo/psalm: ^3.12.2
This package is auto-updated.
Last update: 2024-09-11 17:48:56 UTC
README
动机
当你与 ORM 一起工作时,你需要处理 n+1 查询问题。如果你不熟悉它,你可以在这里了解更多关于它的信息 here。简而言之,这就是 ORM 由于你的代码以懒加载方式访问实体而导致 n+1 查询。
对于 n+1 的修复相当简单,它包括预先加载导致 n+1 的关系(无论是通过获取连接它们,还是对 doctrine 来说更好的是使用 部分脱水)。这些临时修复位于应用程序中获取特定用例根实体的部分。预先加载什么不能在加载时静态定义,因为它实际上取决于以后如何使用获取的实体。
尽管大多数开发者都很好地理解了 n+1 问题,但由于问题的性质,在执行某些应用程序更改时很容易忽略 n+1。考虑一下人们在使用模板引擎中的实体时的情况,他们只是满足了一个新的需求,显示更多一些信息,触发了新的 n+1。或者考虑一下将中心实体重构以替换标量属性与 x-to-one 关系的情况,因此你需要仔细分析重构方法的每个使用情况,以查看是否需要 n+1 修复。这就是 doctrine n+1 detector 发挥作用的地方。一旦启用,它将监听一些 doctrine 事件,检测由 doctrine 触发的 n+1 查询,并最终记录它们,以便用户可以在以后检查它们(或者如果他更喜欢,也许可以围绕这些记录创建警报)。换句话说,你仍然需要预先加载以避免 n+1 查询,但如果在生产中意外地出现 n+1,你有一个工具来让你意识到这一点,以便你可以尽早修复它们。
安装
你可以使用 composer 安装此包
composer require danydev/n-plus-one-detector
用法
你需要初始化检测器并调用 start
,以便尽快开始检测 n+1,然后在请求生命周期中稍后可以检查所有检测到的 n+1。
// Start the n+1 detector at the start of our request handler.
$nPlusOneDetector = new NPlusOneDetector($entityManager);
$nPlusOneDetector->start();
//... normal request lifecycle happens here...
// Inspect n+1 detected just before returning the response
$result = $nPlusOneDetector->getDetectedNPlusOne();
foreach($result->getCollectionStats() as $stat) {
error_log('[N+1-detected] on ' . $stat->getOwnerClass() . ' due to collection of ' . $stat->collectionElementsClass());
}
foreach($result->getProxyStats() as $stat) {
error_log('[N+1-detected] on ' . $stat->getClass());
}
待办事项
- PSR-15 中间件,用于启动和停止,可配置为可选的 PSR-3 日志记录器。
- Symfony 包以集成到他们的 HttpKernel。
- 检测由非拥有方一对一生成的 n+1(此 n+1 是 doctrine 中的设计,但用户可能会通知它很有价值)。
- 检测由具有抽象父类的类中使用的 *-to-many 生成的 n+1(此 n+1 是 doctrine 中的设计,但用户可能会通知它很有价值)。
- 编写一些测试。
- 在 ci 上应用/执行 phpcs、psalm/phpstan。