foreach求和的效率和连接mysql的sum求和的效率

本文对比了两种项目进度更新方法:一种使用PHP foreach循环求和,另一种利用MySQL的SUM函数进行求和。实验证明,在少量数据下,PHP循环更快;但随着数据增加,MySQL SUM性能更优。
范例:
    /**
     * 更新项目进度1 使用foreach循环求和
     */
    public function save_pro_finish_proportion1($pid){
    $list = $this->model_model->where('pid',$pid)->field('id,finish_proportion,weight')->select();
    $sum_weight = 0;
    $sum_finish_proportion = 0;
    foreach ($list as $k=>$v){
         $sum_weight += $v['weight'];
    }
    foreach ($list as $k=>$v){
         $finish_proportion = ($v['finish_proportion']/100)*$v['weight']/$sum_weight;
         $sum_finish_proportion += $finish_proportion;
    }
    echo $sum_finish_proportion;die;
    }
    /**
     * 更新项目进度2 使用mysql的sum求和
     */
    public function save_pro_finish_proportion2($pid){
    $list = $this->model_model->where('pid',$pid)->field('id,finish_proportion,weight')->select();
    $sum_weight = $this->model_model->where('pid',$pid)->sum('weight');
    $sum_finish_proportion = 0;
    foreach ($list as $k=>$v){
         $finish_proportion = ($v['finish_proportion']/100)*$v['weight']/$sum_weight;
         $sum_finish_proportion += $finish_proportion;
    }
    echo $sum_finish_proportion;die;
    }
实验结果:在10条记录的情况下,使用foreach循环求和  要比  使用mysql的sum求和 平均求和并得出结果的速度  要快5ms左右;
        60条数据时,平均值不相上下;
        当数据有400条时候   使用mysql的sum求和  明显要比  使用foreach循环求和 平均值和每一组数据  都要快10ms;
结论 : 数据量小,使用mysql连接开销要比php后台语言循环 开销大 ,一旦数据量变大 应当使用mysql求和更好;
<think>嗯,用户想用MyBatis-Plus的LambdaQueryWrapper来实现按字段求和分组的功能。首先,我需要确认LambdaQueryWrapper是否支持这些操作。记得LambdaQueryWrapper主要用于构建查询条件,而聚合函数分组可能需要使用QueryWrapper的select方法。 用户可能已经知道LambdaQueryWrapper的基本用法,比如eq、ne这些条件构造,但聚合分组可能不太一样。根据引用[3],MyBatis-Plus的Chain分为queryupdate,而Lambda链式提供了类型安全的条件构造。所以可能需要结合select方法来指定聚合函数。 首先,求和的话应该用sum()方法,但LambdaQueryWrapper本身可能没有直接的sum方法。这时候可能需要用select()来指定要查询的列,并加上聚合函数,比如SUM(age)。而分组的话,应该用groupBy()方法,参数是Lambda表达式指定的字段。 然后,用户可能需要返回一个包含聚合结果的对象,所以需要对应的实体类或者VO类来接收结果。例如,创建一个UserSumVO,里面有sumAgegroupByField两个字段。 接着,示例代码部分需要展示如何链式调用selectgroupBy,同时使用lambda表达式来指定字段。这样代码会更简洁,类型安全。要注意的是,select方法中需要传入SqlSelect的列,比如Selectors.sum()来生成SUM语句。 另外,可能需要注意,如果使用group by,select中的字段要么是聚合函数,要么是group by的字段,否则SQL会报错。所以在示例中,select的列应该包括SUM(age)groupField,而group by后面是groupField对应的列。 最后,需要提到相关的Service或Mapper的调用,比如userMapper.selectList(wrapper)来执行查询,并返回VO的列表。这样用户就能得到分组后的求和结果了。 可能还需要检查是否有相关的引用支持,比如引用[3]提到的Lambda链式风格,虽然不支持Kotlin,但Java中是没问题的。引用[4]中的UserDao继承BaseMapper,所以示例中的UserDao应该正确注入使用。 总结步骤:创建VO类,构建LambdaQueryWrapper,使用select方法包含sum分组字段,添加groupBy条件,执行查询,处理结果。同时提醒用户注意字段匹配SQL语法正确性。</think>### 使用 LambdaQueryWrapper 实现字段求和与分组示例 #### 1. 实体类定义 假设存在实体类 `User`,包含字段 `groupField`(分组依据字段) `value`(需要求和的数值字段): ```java @Data public class User { private Long id; private String groupField; private Integer value; } ``` #### 2. 实现求和与分组 通过 `LambdaQueryWrapper` 构建查询条件,结合 `select()` 方法指定聚合函数分组字段: ```java LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.select( // 指定分组字段 User::getGroupField, // 对 value 字段求和,并定义别名 sumValue Selectors.sum(User::getValue, "sumValue") ) .groupBy(User::getGroupField); // 按 groupField 分组 List<Map<String, Object>> result = userMapper.selectMaps(wrapper); ``` #### 3. 结果处理 查询结果 `result` 将返回包含 `groupField` `sumValue` 的键值对集合: ```java result.forEach(map -> System.out.println("分组:" + map.get("groupField") + " 总:" + map.get("sumValue")) ); ``` --- ### 关键步骤解析 1. **`select()` 方法** 使用 `Selectors.sum()` 定义求和表达式,第二个参数为返回结果的别名,需与结果解析时使用的键名一致[^3]。 2. **`groupBy()` 方法** 通过 Lambda 表达式指定分组字段,避免硬编码字段名,保证类型安全[^3]。 3. **`selectMaps()` 方法** 返回 `List<Map<String, Object>>` 结构,适用于未定义 DTO/VO 的场景。若需类型安全,可自定义 DTO 类配合 `select()` 映射字段[^4]。 --- ### 注意事项 - **聚合字段必须显式定义别名** 例如 `Selectors.sum(User::getValue, "sumValue")`,别名需与结果解析时的键名匹配。 - **分组字段需包含在 `select()` 中** 否则可能触发 SQL 语法错误(如 MySQL 的 `ONLY_FULL_GROUP_BY` 模式限制)[^2]。 - **复杂聚合场景建议使用 XML/SQL 注解** 若涉及多表关联或复杂计算,直接编写 SQL 更灵活[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值