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

Laravel查询用户挑战进度如何实现升序排序及分页且不使用foreach循环

性能优化方案:查询层实现进度计算、排序与分页

你现有代码的核心性能问题是全量拉取数据后双层循环计算,同时存在N+1查询,完全无法支撑大数据量场景,下面提供两种可直接实现排序+分页的无foreach方案:

方案1:SQL层直接聚合计算(适合逻辑不复杂的场景)

将missionState方法中统计have_to_mission_count和cert_count的逻辑转化为SQL聚合条件,一次性完成进度计算、排序、分页:

$perPage = 10; // 自定义每页展示条数
$users = \App\Models\ChallengeUserPivot::where('challenge_id', $challenge_id)
    // 关联用户表避免N+1查询
    ->join('users', 'challenge_user_pivots.user_id', '=', 'users.id')
    // 关联当前挑战的所有任务
    ->join('challenge_missions', 'challenge_missions.challenge_id', '=', 'challenge_user_pivots.challenge_id')
    // 左连用户任务完成记录表,统计已完成任务数,条件根据你实际业务调整
    ->leftJoin('user_mission_certs', function ($join) {
        $join->on('user_mission_certs.user_id', '=', 'users.id')
            ->on('user_mission_certs.mission_id', '=', 'challenge_missions.id')
            ->where('user_mission_certs.is_valid', 1); 
    })
    // 聚合计算总任务数、已完成数、进度值
    ->selectRaw('
        challenge_user_pivots.*,
        users.*,
        COUNT(challenge_missions.id) as total_mission,
        COUNT(user_mission_certs.id) as completed_mission,
        (COUNT(user_mission_certs.id) / COUNT(challenge_missions.id)) * 100 as progress
    ')
    ->groupBy('challenge_user_pivots.user_id')
    // 按进度升序排序
    ->orderBy('progress', 'asc')
    // 直接调用Laravel分页方法实现分页
    ->paginate($perPage);

该方案优势:

  • 全程仅执行1次SQL查询,无PHP层循环逻辑,性能不受用户量级增长影响
  • 进度计算、排序逻辑全部下沉到数据库层,无需额外遍历处理结果集
  • 直接复用Laravel原生分页器,自带分页所需的总条数、上一页/下一页标识等参数

方案2:冗余字段预存进度(适合超大数据量、逻辑复杂的场景)

如果missionState的业务逻辑非常复杂,无法转化为SQL条件,就用冗余存储方案:

  1. 给challenge_user_pivots表新增progress(decimal类型)冗余字段
  2. 在用户完成任务、挑战任务配置变更时,通过事件、观察者或者队列异步更新对应用户的progress值
  3. 查询时直接基于冗余字段排序分页,性能达到最优:
$perPage = 10;
$users = \App\Models\ChallengeUserPivot::where('challenge_id', $challenge_id)
    ->with('user') // 预加载用户信息避免N+1
    ->orderBy('progress', 'asc')
    ->paginate($perPage);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:45:02