这个定时任务,从3min优化到200ms。老板,我尽力了!

近期,数据中心系统负荷大,mysql服务器的CPU动辄高达90%以上。代码和数据表存在很大优化空间。

这里分享一个定时任务批量处理数据的优化过程。

先介绍定时任务

先介绍下面2张数据表
字段数据量

platform_order

平台交易订单表

包括 主键自增 id、客户id、客户名称(冗余字段)、 服务商id(levy_id)、服务商名称(levy_name,冗余字段)

付款方式、付款状态、收款人、收款人收款账号(卡号/支付宝/微信)、项目id、付款金额、渠道商、销售代表、

创建时间、最近更新时间、付款完成时间,等等。

550w,每天增量3w

宽表,有多达54个字段。

levy_info

服务商信息表
字段包括 服务商id(levy_id)、服务商名称(levy_name),等若干字段50条,基础信息表,很少新增

项目程序里有一个定时任务,每间隔5分钟,定期为platform_order的冗余字段levy_name赋值。也就是,根据levy表里的信息来更新platform_order表。

最原始的程序实现

我相信这是绝大多数程序员的实现方式。

【第一步】求count: select count(1) from platform_order where levy_name is null

【第二步】分页从数据表获取 levy_name is null 的记录,例如每页1000条,放到List集合里。

【第三步】遍历List集合里的元素,根据记录的levy_id去查levy_info表,得到levy_name,执行SQL: update platform_order set levy_name =#{levy_name} where id =#{id}

这个定时任务启动后,不停刷日志,耗时≈3min

改进后的程序实现

【第一步】求count:SQL同上

【第二步】如果count>0,则执行一条update语句: update platform_order a join levy_info b on a.levy_id =b.levy_id set a.levy_name =b.levy_name where a.levy_name is null

这个实现方式,java着实少了许多行代码,不过,数据库倒是出现慢sql了。 count耗时≈2s + update语句耗时10~12s = 整个job耗时≈15s 。

洪荒之力,优化到200ms以内

【第一步】

不再是傻瓜式地一个 levy_name is null 条件了。而是再加一个 id >#{maxId} 条件。 maxId 值从哪里来?每次定时任务执行完后将最大记录id缓存起来。当然,服务启动后第一次是没有缓存的,就让maxId=0。

再者,执行的sql不是简单的count,而是select levy_id,min (id)as minId,max (id)as maxId from platform_order where id >#{maxId}and levy_name is null group by levy_id

【第二步】

上面的分组查询得到一个List集合,遍历集合元素,同样根据levy_id查levy_info表得到levy_info记录。

然后,如果你跟得上我的节奏,你应该能猜到,执行这样一个SQL:

update platform_order set levy_name=#{levy_name} where levy_id=#{levy_id} and id between #{minId} and #{maxId} and levy_name is null

View Code

顺便说一嘴,根据levy_id获取levy_info记录,我使用了缓存,缓存24h,豪横吧~

【第三步】

缓存最大id —> maxId

经过这个性能优化之后,job的耗时在100ms~200ms之间,这个耗时足可以令伙伴们尖叫!

这个定时任务,从3min优化到200ms。老板,我尽力了!

related MySql团队开发规范

11)单表字段数不要太多,建议最多不要大于50个。过度的宽表对性能也是很大的影响。
12)MySQL在处理大表时,性能就开始明显降低,所以建议单表物理大小限制在16GB,表中数据行数控制在2000W内。
业内的规则是超过2000W性能开始明显降低。但是这个值是灵活的,你可以根据实际情况进行测试来判断,比如阿里的标准就是500W,百度的确是2000W。实际上是否宽表,单行数据所占用的空间都有起到作用的。
13)如果数据量或数据增长在前期规划时就较大,那么在设计评审时就应加入分表策略,后续会有专门的文章来分析数据拆分的做法:垂直拆分(垂直分库和垂直分表)、水平拆分(分库分表和库内分表)。

Original: https://www.cnblogs.com/buguge/p/16812025.html
Author: buguge
Title: 这个定时任务,从3min优化到200ms。老板,我尽力了!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/686225/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SSM(Spring,SpringMVC,Mybatis)框架整合项目

    快速上手SSM(Spring,SpringMVC,Mybatis)框架整合项目 环境要求: IDEA MySQL 8.0.25 Tomcat 9 Maven 3.6 数据库环境:创…

    技术杂谈 2023年7月11日
    079
  • 面向对象编程-基础

    面向对象是一种”建模思想” 把现实中的各种事物”虚拟化到程序中”(定义类就是一种封装) 类:对现实生活中一类具有共同属性和行为的事物…

    技术杂谈 2023年6月21日
    083
  • Microk8s 安装 与使用指南

    我们已经知道,Kubernetes 是基于容器的应用程序的首选编排平台,可以自动部署和扩展这些应用程序,并简化维护操作。但是,Kubernetes也有其自身的复杂性挑战。那么,企业…

    技术杂谈 2023年5月30日
    0117
  • quartz框架(六)-ThreadPool

    本篇博文,博主将介绍Quartz框架中ThreadPool线程池相关的内容。线程池顾名思义,就是一个可以帮助我们来进行线程资源管理的对象。在web开发中,常见的就有数据库连接池,h…

    技术杂谈 2023年7月24日
    080
  • 对象数组排序 和 类比JDK实现 sort()的方法

    1.定义自己的 MyComparable 接口 1 package Test.treeSetDemo; 2 3 public interface MyComparable { 4 …

    技术杂谈 2023年6月21日
    088
  • playwright 打包程序 无法定位程序输入点gethostname于动态链接库ws2_32.dll上

    node.exe 无法找到入口playwright 打包程序在win7上边报错需要替换包里边的node.exe程序 win7支持10-13 版本node 默认下载为16node-1…

    技术杂谈 2023年7月11日
    097
  • cocos 资源工作流程

    前面的话 本文将详细介绍 cocos 中的资源工作流程 【同步性】 资源管理器中的资源和操作系统的文件管理器中看到的项目资源文件夹是同步的 在资源管理器中对资源的移动、重命名和删除…

    技术杂谈 2023年5月30日
    0124
  • ThreeJS中创建文字的几种方法

    1. DOM + CSS 传统html5的文字实现,用于添加描述性叠加文字的方法。一般使用绝对定位,并且保证z-index够大,用于显示在3D场景之上。 优点:与CSS3D效果一致…

    技术杂谈 2023年7月24日
    067
  • 4、Swift协程详解:结构化并发与TaskGroup

    TaskGroup 的基本用法 我们现在已经知道怎么在自己的程序里面调用异步函数了。 不难发现,调用异步函数的关键点是创建 Task 的实例。通过 Task 的构造器或者 deta…

    技术杂谈 2023年6月1日
    077
  • Pillow 图片处理模块

    pic = Image.open(’11.jpg’) im = Image.new(‘RGB’, (128, 128), (255, 0, 0)) im1 = Image.new(…

    技术杂谈 2023年6月21日
    097
  • 2022.22 如何提升技术能力

    最近,看到文章《关于技术能力的思考和总结》,里面的一些点还是值得技术人反思学习的。 对于什么是技术能力,作者提炼了一个模型如下: 首先,技术人要通过练掌握术,提升技术能力,成为团队…

    技术杂谈 2023年5月30日
    0105
  • 3D Math Keynote 4

    导航 3D Math Keynote 4 【 3D Math Keynote 4】 1、三角带。 合并三角带能够提升渲染效率。 三角扇。 2、边缩坍,将边缩减为顶点 。 网格消减,…

    技术杂谈 2023年5月31日
    093
  • 性能测试案例全过程方案六———购物流程(重要!!!)

    代码改变世界 Cnblogs Dashboard Login 2022-01-15 22:19 清风软件测试开发 阅读(9 ) 评论() 编辑 性能测试案例全过程方案六 模拟多用户…

    技术杂谈 2023年5月31日
    0119
  • 你还有什么问题吗?

    在面试过程中,一般都会有一个固定环节,那就是在临近结束时,面试官会问求职者: 你还有什么问题吗? 其实,这是一个很好的了解公司,了解未来团队的机会,但很多求职者却不知道问什么,或者…

    技术杂谈 2023年6月21日
    078
  • 如何使能uboot的debug开关?

    答: 直接在 Original: https://www.cnblogs.com/dakewei/p/14010217.htmlAuthor: JelloTitle: 如何使能ub…

    技术杂谈 2023年5月31日
    0129
  • jest beforeEach 和beforeAll区别

    写测试的时候,我们经常需要进行测试之前做一些准备工作,和在进行测试后需要进行一些整理工作。Jest提供辅助函数来处理这个问题。 为多次测试重复设置如果你有一些要为多次测试重复设置的…

    技术杂谈 2023年5月30日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球