You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent查询与集合优化:订单统计查询优化诉求

优化订单统计查询方案

直接用一次数据库聚合查询替代三次全量数据拉取,大幅提升性能,代码如下:

public function index(Order $order)
{
    // 一次查询获取按年份分组的所有统计数据
    $orderStats = Order::selectRaw(
        "YEAR(created_at) as year,
         SUM(total) as total_amount,
         SUM(CASE WHEN payment_confirmed = 1 THEN total ELSE 0 END) as paid_amount,
         SUM(CASE WHEN payment_confirmed = 0 THEN total ELSE 0 END) as unpaid_amount"
    )
    ->groupBy('year')
    ->orderBy('year')
    ->get()
    ->keyBy('year');

    // 整理成视图需要的三个数组格式
    $orders = $orderStats->map(fn($stat) => $stat->total_amount)->toArray();
    $paid_orders = $orderStats->map(fn($stat) => $stat->paid_amount)->toArray();
    $unpaid_orders = $orderStats->map(fn($stat) => $stat->unpaid_amount)->toArray();

    return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}

核心优化点:

  • 减少查询次数:从三次全表查询缩减为一次聚合查询,降低数据库IO和连接开销
  • 数据库层面处理聚合:把分组、求和操作交给数据库完成,避免将全量订单数据加载到PHP内存中处理,数据量越大性能提升越明显
  • 精简逻辑:通过CASE WHEN语句在一次查询中同时计算总金额、已支付金额、未支付金额,无需多次过滤数据
  • 日期处理优化:直接用数据库函数YEAR(created_at)提取年份,避免在PHP中逐个处理日期格式

注:原代码中paid_orders的分组逻辑存在冗余判断(已过滤payment_confirmed=1的订单,却仍判断payment_confirmed == false),优化后的代码按原逻辑默认使用订单创建年份分组,若实际业务需按支付年份统计,可将YEAR(created_at)替换为YEAR(paid_at)(需确保模型有paid_at字段)。

内容的提问来源于stack exchange,提问作者McRui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 12:05:28