多层for循环嵌套使用sql优化
哇,已经有一年多没有写了
这里来记录一下一个小小的优化
原因:领导发现每天凌晨2点cpu使用率激增
从图可以看出来很有规律性,可以知道这是某个定时脚本的原因,根据执行时间可以定位到该定时脚本。看一看定时脚本的逻辑原来这个脚本是对过去30天每一天--每种票类型--每个省份完成订单总数和售票总数的统计和更新。这里附上一段代码截图
可以看出来之前代码套了3层for循环,按照每天去循环查每种票类型对应每一个省份的逻辑,从order(订单表)中依次统计对应create_time,order_type,province匹配并且订单状态为已完成的订单数和售票数,存在即更新不存在则插入的逻辑更新order_source(客源地订单统计表)。一共执行了 30(天)*7(票类型)*34(省份)*2=14280条sql语句。
如果一开始让我实现这个功能我的思路可能也是按照如果订单创建,无论订单的状态什么时候更新为已完成,这个订单始终是订单创建那一天完成的订单。之所以要不断更新过去30天的数据是因为存在这样的情况,比如用户提前一周比如4.5买好票,但是5.5号才消费也就是5.5号订单状态才变为已完成。为了统计到这一个完成的订单要花费好多次无用的查询。
优化后的逻辑。是按照订单完成的update_time字段来查询,不管你的订单是什么时候创建的,订单什么时候更新就属于更新的那一天完成的订单。所以我们可以只统计前一天订单状态更新为已完成的订单,按照update_time进行查询,按照省份,订单类型,更新时间进行分组GroupBy("order_province,type,date_format(update_time, '%Y-%m-%d')"),我们就可以查出前一天已完成订单的省份,类型,时间,然后将数据进行拼接insert sql语句,只需要两条sql语句可以完成统计。上线后cpu使用如下图,可以看出使用cpu低了好多,效果很明显
优化思路:1.避免在for循环中使用sql
2.充分理解业务需求