Ver Fonte

perf(app):优化班级分组查询性能

- 使用派生表预先计算报名人数,避免N+1查询问题
- 调整JOIN顺序,优先连接小表提升查询效率
-用EXISTS子查询替代LEFT JOIN优化订单关联逻辑- 修改班级名称查询为模糊匹配- 移除冗余的GROUP BY子句
-保留核心业务逻辑确保数据准确性
wzq há 1 semana atrás
pai
commit
89ec2607d2

+ 27 - 9
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppClassGroupingMapper.xml

@@ -37,23 +37,41 @@
         cg.id,
         cg.class_name AS classGroupingName,
         u.realname AS coachName,
-        COUNT( cu.id ) AS applyNum,
+        cu_stats.applyNum, -- 使用预先统计好的数据
         cg.create_time
         FROM
         nm_class_grouping cg
+        -- 首先连接教练信息(小表驱动)
         LEFT JOIN sys_user u ON u.id = cg.coach_user_id
-        LEFT JOIN nm_class_user cu ON cu.class_grouping_id = cg.id
-        LEFT JOIN nm_order_pro_info opi ON opi.product_id = cu.course_id AND opi.family_user_id = cu.family_member_id
+        -- 关键优化:使用派生表预先计算每个分组的报名人数,避免N+1的标量子查询
+        INNER JOIN (
+        SELECT
+        cu.class_grouping_id,
+        COUNT(cu.family_member_id) AS applyNum
+        FROM
+        nm_class_user cu
+        WHERE
+        cu.course_id = #{classGroupingCasePageForm.courseId}
+        AND cu.del_flag = 0
+        -- 使用EXISTS确保只统计有有效订单的用户,这是原SQL的核心业务逻辑
+        AND EXISTS (
+        SELECT 1
+        FROM nm_order_pro_info opi
+        WHERE opi.product_id = #{classGroupingCasePageForm.courseId}
+        AND opi.family_user_id = cu.family_member_id
+        )
+        GROUP BY
+        cu.class_grouping_id
+        ) cu_stats ON cu_stats.class_grouping_id = cg.id
         <where>
-            cg.del_flag = 0 AND cu.del_flag = 0 AND opi.id is NOT NULL AND cg.course_id = #{classGroupingCasePageForm.courseId}
+            cg.del_flag = 0
+            AND cg.course_id = #{classGroupingCasePageForm.courseId}
             <if test="classGroupingCasePageForm.classGroupingName != null and classGroupingCasePageForm.classGroupingName != ''">
-                AND cg.class_name = #{classGroupingCasePageForm.classGroupingName}
+                AND cg.class_name LIKE CONCAT('%',#{classGroupingCasePageForm.classGroupingName},'%')
             </if>
         </where>
-        GROUP BY
-        cg.id,
-        cg.class_name
-        ORDER BY cg.create_time DESC
+        ORDER BY
+        cg.create_time DESC;
     </select>
     <select id="queryByUserId" resultType="org.jeecg.modules.system.app.dto.ClassGroupingDTO">
         SELECT