一次业务逻辑优化,居然解决了MySQL CPU消耗800%的性能问题!

扫描下方海报二维码,试听课程:
mysql

(课程详细大纲,请参见文末)面试

=========================================sql

文章来自头条号:波波说运维数据库

=========================================
缓存

概述

最近接到IDC监控告警说某台服务器cpu太高,下面记录下故障排查的过程,仅供参考,这里主要看思路,细节不重要。bash

一、观察服务器资源消耗

能够看到服务器表现为cpu问题,内存消耗正常。服务器



1.一、查看具体cpu运维

ps -mp 2289 -o THREAD,tid,time分布式



1.二、找到耗时最高的线程TID,并将其线程ID转换为16进制格式:优化

printf "%x\n" tid


1.三、打印线程的堆栈信息,thread dump

jstack pid |grep tid -A 30

进一步分析堆栈信息

二、检查数据库线程

这里发现大概有8个线程,并且都是同一条sql


三、查看sql执行计划

这个单条sql只须要2s就能够跑完,不过看执行计划是走了全表扫描,并无走索引



四、慢查询分析

set global slow_query_log=on;set global long_query_time=30;set global log_output='TABLE';show variables like '%slow%';select * from mysql.slow_log order by 1;复制代码


如下是由于先开了没有走索引就记录下来,因此能够看到这条sql,可是开了慢查询后并无超过30s的慢sql.


五、定时任务?

跟开发确认后是有个定时任务,每次都须要去查每一个用户的考勤时间,最后再汇总统计,这个定时任务须要跑一天的时间。

这里问题主要是嵌套循环,外层循环遍历工号(8000),内层循环遍历天数(30天),而后内层循环每次查数据都须要去跟数据库作一次交互,在插入数据到缓存,最后汇总计算到汇总表。

六、优化方案

一、汇总表拆分

经常使用字段划为一张表,不经常使用字段划分为另外一张表,而后经常使用字段这些只作汇总计算,不走循环,不经常使用字段(如婚假、病假等)这些走循环。


二、优化单条查询

这个建索引,控制在1s内

--大表建索引,驱动表不建索引create index idx_hwb1 on t_att_dd_attendance_info(user_id,class_id,check_type,plan_check_time)复制代码


三、逻辑优化

这里跟开发提了把逻辑改了,不过开发还没实现,因此就不贴实现代码了。逻辑大体以下:



END

《21天互联网Java进阶面试训练营(分布式篇)》详细目录,扫描图片末尾的二维码,试听课程

相关文章
相关标签/搜索