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

优化Laravel查询:如何用集合方法将24次查询降为1次

优化方案

完全可以通过1次查询+Laravel集合分组实现需求,你可以先批量拉取所有符合条件的销售数据做聚合,后续遍历直接从聚合结果中取值即可,完全避免循环查询。

第一步:构造单次聚合查询

我们直接筛选出产品ID在指定范围、年份在2014-2021之间的所有销售记录,按product_id和年份字段分组统计数量,全程仅执行1次SQL:

@php
$products = [101 => 'product-a', 102 => 'product-b', 103 => 'product-c'];
$from_year = 2014;
$to_year = 2021;
$productIds = array_keys($products);

// 假设销售记录的年份字段为year,若需从创建时间取年份可替换为YEAR(created_at)
// 如果原getSales方法有额外筛选条件(比如有效订单、已支付等),直接补充where条件即可
$salesStats = Products::whereIn('product_id', $productIds)
    ->whereBetween('year', [$from_year, $to_year])
    ->selectRaw('product_id, year, count(*) as sales_count')
    ->groupBy('product_id', 'year')
    ->get()
    // 集合做二级分组,第一层key为产品ID,第二层key为年份
    ->groupBy(['product_id', 'year']);
@endphp

第二步:遍历直接取预统计结果,不再查库

@php
foreach ($products as $product_id => $product_title) {
    echo "<h1>$product_title</h1>";
    for ($year = $from_year; $year <= $to_year; $year++) {
        // 你原代码此处重复输出了产品名,大概率是笔误,调整为输出年份
        echo "<h3>{$year}年销量</h3>";
        // 无对应销量数据时默认返回0,和原count()返回结果完全一致
        echo $salesStats->get($product_id, collect())->get($year, collect())->first()?->sales_count ?? 0;
    }
}
@endphp

优化说明

  • 全程仅执行1次数据库查询,完全消除循环查询的性能损耗
  • 所有结果取值都在内存中通过Laravel集合完成,运行效率远高于循环查库
  • 兼容无销量的场景,返回值和原有逻辑完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:27:03