2017-09-13 68 views
0

我在这个项目中使用Zend Framework 3Doctrine2如何提高上市嵌套主义实体的性能

我有一个嵌套的实体,它是像树层次结构一样构建的。

[Project] 1 - n [WorkOrders] 1 - n [WorkOrderItems] 

每个WorkOrderItem都有一个状态 - 简化的例子中该状态可以是1没有完成或2为成品。我现在想通过遍历所有WorkOrderItems,以显示该项目的进展情况,并计算百分比,像这样:

$finishedWorkOrderItems = 0; 
$totalWorkOrderItems = 0; 
foreach ($this->getWorkOrders() as $workOrder) { 
    foreach ($workOrder->getWorkOrderItems() as $workOrderItem) { 
     if ($workOrderItem->getStatus() == WorkOrderItem::STATUS_FINISHED) { 
      $finishedWorkOrderItems++; 
     } 
     $totalWorkOrderItems++; 
    } 
} 
return 100/$totalWorkOrderItems * $finishedWorkOrderItems; 

当显示50个项目的加载时,直到观点是完全呈现的清单是非常高的 - 之间7和9秒。在没有进度的情况下渲染列表时,渲染时间显着更短 - 介于0.5和2之间。

我试图在SELECT语句中使用自定义DQL该项目,并加入所需要的数据,像这样:

$queryBuilder = $entityManager->createQueryBuilder(); 

    $queryBuilder 
     ->select(['p', 'o', 'oi']) 
     ->from(Project::class, 'p') 
     ->join('p.orders', 'o') 
     ->join('o.orderItems', 'oi') 
     ->groupBy('p'); 

这给了我没有可测量的性能提升。

回答

1

为什么不直接从DQL获得的,而不是一个嵌套循环的总数

SELECT p, 
COUNT(DISTINCT o.id) AS totalOrders, 
COUNT(oi.id) AS totalOrdersItems, 
SUM(CASE WHEN oi.status = 'some status' THEN 1 ELSE 0 END) AS totalWorkedOrdersItems 
FROM Bundle\Entity\Project p 
LEFT JOIN p.orders o 
LEFT JOIN o.orderItems oi 
GROUP BY p.id