在各种情况下,当我尝试应用 * M *VC 模式时,我似乎无法优化这种情况,因为我有嵌套循环加载不同类型的模型,它们都有自己的(单个)查询来从数据库加载实体。
在下面的代码中,我试图描述这种情况。如您所见,执行相同的查询 500 次对于性能来说看起来并不是很有希望。同样让 OrderLine 急于在同一个查询中获取产品并不是我想要的,我认为它可能会解决说明性场景的问题。
显示当前未结订单的所有产品库存和预订
// 1 query to get all open (undelivered) orders
foreach (Order::getOpenOrders() as $order) {
// for example; 50 open orders, so ~50 times this query
foreach ($order->getOrderLines() as $line) {
// for example; avg 10 lines per order, so ~50x~10= ~500 times this query
foreach ($line->getProduct() as $product) {
$stock = $product->getStock(); // ~500 times, heavy query
echo $product->getName().': '.$line->getAmount().' times ordered, '.
$stock.' times in stock';
}
}
}
我知道缓存之类的东西可以将 500 个查询的性能问题降到最低,但这只是说明问题的一个例子,而不是它的影响。
我已经想到了一些不同类型的解决方案,但这些都不是真正适合我想解决这个问题的通用方式:
- 用Query builder做一些花哨的事情,神奇地将模型中的不同查询合并到某种复杂的 JOIN 中?
- 添加选项以事务方式加载模型。不确定是否可能,我猜会变得非常复杂。
- 使模型可配置为延迟/急切加载(难以编码?)
- 为每个场景创建自定义方法,例如: Order::getSumAmountFromOrderLinesByProduct($product) // ;) 不太灵活且可维护性低。此外,非常不同的模型在某种程度上对其他类的(加载)行为负责。
解决这个多级/嵌套模型加载问题的最常见/最佳 MVC 方法是什么?
也非常欢迎有关此主题的文档或关键字。