Php “如何使销售报告更准确”;“可伸缩”吗;?
我构建了一个应用程序来跟踪销售情况。在我的客户视图中,我希望列一个每个客户的总销售额,但随着客户群的增长,列表的加载速度越来越慢。这就是我所做的(简化): 控制器:Php “如何使销售报告更准确”;“可伸缩”吗;?,php,sql,laravel-5,Php,Sql,Laravel 5,我构建了一个应用程序来跟踪销售情况。在我的客户视图中,我希望列一个每个客户的总销售额,但随着客户群的增长,列表的加载速度越来越慢。这就是我所做的(简化): 控制器: $customers = App\Customer::get(); 视图: 型号: public function totalSales() { $invoiceLines = InvoiceLine::whereHas('invoice', function ($query) { $query->
$customers = App\Customer::get();
视图:
型号:
public function totalSales()
{
$invoiceLines = InvoiceLine::whereHas('invoice', function ($query) {
$query->where('customer_id', $this->id);
})->get();
$sales = $invoiceLines->reduce(function ($carry, $invoiceLine) {
return $carry + ($invoiceLine->quantity * $invoiceLine->pricePerUnit);
});
return $sales ?: 0;
}
使此视图/报告更具“可伸缩性”的最佳方法是什么
我一直在考虑创建一个命令,该命令计算每个客户一夜之间的总销售额,并将结果放入客户表中,但这意味着白天的数字将不准确…这似乎是一个非常有趣的问题 我一直在考虑创建一个计算总数的命令 一夜之间每个客户的销售额,并将结果放入客户表中 这是一个很好的选择 但这意味着白天的数字不会准确 您可以通过执行以下操作来保持数字的准确性: 通过在每次开具发票时增加customers表计数 这应该适用于总销售额
customer\u id
列上有索引SUM
”的方法groupby
在2上执行“SQLSUM
。这样做将取代#2
- 加速应用程序的一个好方法是避免在循环中调用数据库。这就是#3所建议的(本例中的循环是您视图中的
,数据库调用是@foreach
中的InvoiceLine::…->get();
totalSales()
添加索引(如果缺少)并减少对DB的调用次数将产生最佳结果 我对Laravel的了解有限,但使用原始SQL实现这一点的一种方法是:
SELECT c.name, ts.totalSales
FROM customer c
INNER JOIN (
SELECT customer_id, SUM(quantity * pricePerUnit) as totalSales
FROM invoice
GROUP BY customer_id
) ts ON c.id = ts.customer_id
你可以看到你试图打印的所有数据是如何一次被提取出来的?我想你可能会想用拉威尔的雄辩的东西来写出来。基于上述答案,我得出了以下解决方案: 我创建了一个事件:
App\Events\InvoiceSaved
,每次“触摸”发票(创建、更新或删除)时都会发送该事件。App\Events\InvoiceSaved
事件将计算客户的总销售额,并将结果添加到customers表(额外字段total\u sales).现在我可以只查询我的客户表,需要查询一个关系。加载时间从7秒下降到0.5秒
SELECT c.name, ts.totalSales
FROM customer c
INNER JOIN (
SELECT customer_id, SUM(quantity * pricePerUnit) as totalSales
FROM invoice
GROUP BY customer_id
) ts ON c.id = ts.customer_id