1、现象
执行近100W条Elastic-job任务时,扫描代执行任务耗时5.5秒,数据库socketTimeout设置5S超时,导致超时异常,从而退出任务。
2、排查
利用阿里云ARMS监控应用
1、安装Java探针
-
开通ARMS,并创建应用。
-
下载Java探针包并解压。
-
在Java应用启动脚本中增加-javaagent:/{user.workspace}/ArmsAgent/arms-bootstrap-1.7.0-SNAPSHOT.jar-Darms.licenseKey=xxx -Darms.appId=xxx (appId和licenseKey根据页面分配的信息填写)
-
打开ARMS页面,数据开始上报,验证Java探针安装成功。
2、在应用概览中发现“慢”可疑线索
进入ARMS应用拓扑图。在应用概览中我们能够明显地看到今天系统中有“慢SQL”5次。
3、监控到慢SQL
SELECT
COUNT(DISTINCT job_id)
FROM
job_task
WHERE
record_status = 0
AND job_member_month = CONCAT('2020-02', '-01')
AND task_status = 1
AND next_exec_time <= now();
3、解决
- 新建联合索引优化提升查询耗时
ALTER TABLE `job_task_month` ADD INDEX `idx_gmt_create` (`task_id`,`task_status`,`next_exec_time`,`record_status`) USING BTREE;
- 优化底层查询sql
低效率:select distinct userid,username from user,userinfo where user.userid=userinfo.userid
高效率:select userid,username from user where exists (select 'T' from userinfo where userinfo.userid=user.userid)
4、总结
- 为什么DISTINCT效率低
一同使用 DISTINCT 和 COUNT 关键词,来计算非重复结果的数目。
在mysql的优化中,有一条是:大量的排序操作影响系统性能,所以尽量减少排序操作。GROUP BY、ORDER BY、 ROLLUP、DISTINCT等都会产生排序。少用DISTINCT!
- 需要对比时的SQL语句选择
应该使用 select count(*) from (select distinct col_name,... from table) as temp; 这样的查询时间将大大的缩短。
如果查询频繁,新增所以提高查询效率。