栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mysql cpu 占比过高问题解决

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql cpu 占比过高问题解决

  • 1 首先我们找到mysql占比高的进程号PID
top

  • 2 根据PID找到mysql的os_thread_id
 top -H -p 2559


我们这里可以明显看到有个pid=16815的程序在占用cpu进程 那么我们找到这进行查询的慢sql
这里可以看到是哪个主机连接的信息

SELECt
	a. USER,
	a. HOST,
	a.db,
	b.thread_os_id,
	b.thread_id,
	a.id processlist_id,
	a.command,
	a.time,
	a.state,
	a.info
FROM
	information_schema. PROCESSLIST a,
	PERFORMANCE_SCHEMA .threads b
WHERe
	a.id = b.processlist_id
AND b.thread_os_id = 16804;

  • 我们最终要的是sql 那么执行下面找个就可以找到高id的进程所属的sql
SELECt
	*
FROM
	PERFORMANCE_SCHEMA.events_statements_current
WHERe
	thread_id = (
		SELECt
			thread_id
		FROM
			PERFORMANCE_SCHEMA .threads
		WHERe
			thread_os_id = 16804
	) ;


接下来优化sql就行了

这里我们随意找一处比较耗时的sql来做统计
这应该是一位非常懂这块业务的哥们写的 我们来看一下

EXPLAIN
SELECt g.*
FROM (
	SELECt DISTINCT ru.id AS unitId, ru.unit_name AS unitName, ru.create_time, ru.baseid, ru.entid
		, p.id AS postId, p.post_name AS postName, IFNULL(a.patrolNum, 0) AS patrolNum
		, IFNULL(ht.hiddenNum, 0) AS hiddenNum, b.postRiskLevel
		, b.postRiskLevelText, c.unitRiskLevel, c.unitRiskLevelText
	FROM drh_risk_unit_post rup
		LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
		LEFT JOIN ent_post p ON p.id = rup.post_id
		LEFT JOIN (
			SELECt COUNT(1) AS patrolNum, pp.post_id
			FROM drh_post_patrol pp
			GROUP BY pp.post_id
		) a
		ON a.post_id = rup.post_id
		LEFT JOIN (
			SELECt COUNT(1) AS hiddenNum, h.post_id
			FROM drh_hidden h
			GROUP BY h.post_id
		) ht
		ON ht.post_id = rup.post_id
		LEFT JOIN (
			SELECt llt.*, dt.item_text AS postRiskLevelText
			FROM (
				SELECt ht1.*
				FROM (
					SELECt a.*, rup.risk_unit_id
					FROM drh_risk_unit_post rup
						LEFT JOIN (
							SELECt MIN(hft.risk_level) AS postRiskLevel, pr.post_id
							FROM (
								SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
								FROM drh_post_result_hazar_factors hf
								GROUP BY hf.fk_id
							) hft
								LEFT JOIN drh_post_result pr ON pr.id = hft.fk_id
							WHERe pr.post_id IS NOT NULL
							GROUP BY pr.post_id
						) a
						ON a.post_id = rup.post_id
						LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
					WHERe ru.unit_source = '1'
				) ht1
				UNIOn ALL
				SELECt ht2.*
				FROM (
					SELECt a.*, rup.risk_unit_id
					FROM drh_risk_unit_post rup
						LEFT JOIN (
							SELECt MIN(hft.risk_level) AS postRiskLevel, sm.post_id
							FROM (
								SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
								FROM drh_post_result_hazar_factors hf
								GROUP BY hf.fk_id
							) hft
								LEFT JOIN drh_safety_matters sm ON sm.id = hft.fk_id
							WHERe sm.post_id IS NOT NULL
							GROUP BY sm.post_id
						) a
						ON a.post_id = rup.post_id
						LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
					WHERe ru.unit_source = '2'
				) ht2
			) llt
				LEFT JOIN sys_dict_item dt ON llt.postRiskLevel = dt.item_value
				LEFT JOIN sys_dict d ON dt.dict_id = d.id
			WHERe d.dict_code = 'drh_inherent_risk_level'
		) b
		ON b.risk_unit_id = rup.risk_unit_id
			AND b.post_id = rup.post_id
		LEFT JOIN (
			SELECt tll.*, dt.item_text AS unitRiskLevelText
			FROM (
				SELECt ull.risk_unit_id, MIN(ull.postRiskLevel) AS unitRiskLevel
				FROM (
					SELECt ht1.*
					FROM (
						SELECt a.*, rup.risk_unit_id
						FROM drh_risk_unit_post rup
							LEFT JOIN (
								SELECt MIN(hft.risk_level) AS postRiskLevel, pr.post_id
								FROM (
									SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
									FROM drh_post_result_hazar_factors hf
									GROUP BY hf.fk_id
								) hft
									LEFT JOIN drh_post_result pr ON pr.id = hft.fk_id
								WHERe pr.post_id IS NOT NULL
								GROUP BY pr.post_id
							) a
							ON a.post_id = rup.post_id
							LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
						WHERe ru.unit_source = '1'
					) ht1
					UNIOn ALL
					SELECt ht2.*
					FROM (
						SELECt a.*, rup.risk_unit_id
						FROM drh_risk_unit_post rup
							LEFT JOIN (
								SELECt MIN(hft.risk_level) AS postRiskLevel, sm.post_id
								FROM (
									SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
									FROM drh_post_result_hazar_factors hf
									GROUP BY hf.fk_id
								) hft
									LEFT JOIN drh_safety_matters sm ON sm.id = hft.fk_id
								WHERe sm.post_id IS NOT NULL
								GROUP BY sm.post_id
							) a
							ON a.post_id = rup.post_id
							LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
						WHERe ru.unit_source = '2'
					) ht2
				) ull
				GROUP BY ull.risk_unit_id
			) tll
				LEFT JOIN sys_dict_item dt ON tll.unitRiskLevel = dt.item_value
				LEFT JOIN sys_dict d ON dt.dict_id = d.id
			WHERe d.dict_code = 'drh_inherent_risk_level'
		) c
		ON c.risk_unit_id = rup.risk_unit_id
) g
WHERe g.postRiskLevelText IS NOT NULL
	AND g.entid = 1
	AND g.baseid = 1
ORDER BY g.create_time DESC
LIMIT 10;

耗时22秒 接下来我们分析下
我们通过分析得出 这里面的tablederived2 的rows是一个笛卡尔积 他的数量等于id=2的所有操作 ,其实通过sql可以看出这里不难得出子查套子查询 导致查询效率低

一个主表 left 两个子查询后 外面又套了一个子查询
意思是 子查询 套子查询 导致查询结果比较慢,那么我们就这样优化 如下

SELECt DISTINCT ru.id AS unitId, ru.unit_name AS unitName, ru.create_time, ru.baseid, ru.entid
		, p.id AS postId, p.post_name AS postName, IFNULL(a.patrolNum, 0) AS patrolNum
		, IFNULL(ht.hiddenNum, 0) AS hiddenNum, b.postRiskLevel
		, b.postRiskLevelText, c.unitRiskLevel, c.unitRiskLevelText
	FROM drh_risk_unit_post rup
		LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
		LEFT JOIN ent_post p ON p.id = rup.post_id
		LEFT JOIN (
			SELECt COUNT(1) AS patrolNum, pp.post_id
			FROM drh_post_patrol pp
			GROUP BY pp.post_id
		) a
		ON a.post_id = rup.post_id
		LEFT JOIN (
			SELECt COUNT(1) AS hiddenNum, h.post_id
			FROM drh_hidden h
			GROUP BY h.post_id
		) ht
		ON ht.post_id = rup.post_id
		LEFT JOIN  
     (
SELECt llt.*, dt.item_text AS postRiskLevelText
			FROM (
				SELECt ht1.*
				FROM (
					SELECt a.*, rup.risk_unit_id
					FROM drh_risk_unit_post rup
						LEFT JOIN (
							SELECt MIN(hft.risk_level) AS postRiskLevel, pr.post_id
							FROM (
								SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
								FROM drh_post_result_hazar_factors hf
								GROUP BY hf.fk_id
							) hft
								LEFT JOIN drh_post_result pr ON pr.id = hft.fk_id
							WHERe pr.post_id IS NOT NULL
							GROUP BY pr.post_id
						) a
						ON a.post_id = rup.post_id
						LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
					WHERe ru.unit_source = '1'
				) ht1
				UNIOn ALL
				SELECt ht2.*
				FROM (
					SELECt a.*, rup.risk_unit_id
					FROM drh_risk_unit_post rup
						LEFT JOIN (
							SELECt MIN(hft.risk_level) AS postRiskLevel, sm.post_id
							FROM (
								SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
								FROM drh_post_result_hazar_factors hf
								GROUP BY hf.fk_id
							) hft
								LEFT JOIN drh_safety_matters sm ON sm.id = hft.fk_id
							WHERe sm.post_id IS NOT NULL
							GROUP BY sm.post_id
						) a
						ON a.post_id = rup.post_id
						LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
					WHERe ru.unit_source = '2'
				) ht2
			) llt
				LEFT JOIN sys_dict_item dt ON llt.postRiskLevel = dt.item_value
				LEFT JOIN sys_dict d ON dt.dict_id = d.id
			WHERe d.dict_code = 'drh_inherent_risk_level'
     )
    b
		ON b.risk_unit_id = rup.risk_unit_id
			AND b.post_id = rup.post_id
		LEFT JOIN (
       SELECt tll.*, dt.item_text AS unitRiskLevelText
			FROM (
				SELECt ull.risk_unit_id, MIN(ull.postRiskLevel) AS unitRiskLevel
				FROM (
					SELECt ht1.*
					FROM (
						SELECt a.*, rup.risk_unit_id
						FROM drh_risk_unit_post rup
							LEFT JOIN (
								SELECt MIN(hft.risk_level) AS postRiskLevel, pr.post_id
								FROM (
									SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
									FROM drh_post_result_hazar_factors hf
									GROUP BY hf.fk_id
								) hft
									LEFT JOIN drh_post_result pr ON pr.id = hft.fk_id
								WHERe pr.post_id IS NOT NULL
								GROUP BY pr.post_id
							) a
							ON a.post_id = rup.post_id
							LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
						WHERe ru.unit_source = '1'
					) ht1
					UNIOn ALL
					SELECt ht2.*
					FROM (
						SELECt a.*, rup.risk_unit_id
						FROM drh_risk_unit_post rup
							LEFT JOIN (
								SELECt MIN(hft.risk_level) AS postRiskLevel, sm.post_id
								FROM (
									SELECt hf.fk_id, MIN(hf.risk_level) AS risk_level
									FROM drh_post_result_hazar_factors hf
									GROUP BY hf.fk_id
								) hft
									LEFT JOIN drh_safety_matters sm ON sm.id = hft.fk_id
								WHERe sm.post_id IS NOT NULL
								GROUP BY sm.post_id
							) a
							ON a.post_id = rup.post_id
							LEFT JOIN drh_risk_unit ru ON ru.id = rup.risk_unit_id
						WHERe ru.unit_source = '2'
					) ht2
				) ull
				GROUP BY ull.risk_unit_id
			) tll
				LEFT JOIN sys_dict_item dt ON tll.unitRiskLevel = dt.item_value
				LEFT JOIN sys_dict d ON dt.dict_id = d.id
			WHERe d.dict_code = 'drh_inherent_risk_level'
     ) 
    c
		ON c.risk_unit_id = rup.risk_unit_id
    WHERe 
    b.postRiskLevelText IS NOT NULL
    and ru.entid = 1
    and ru.baseid = 1
    ORDER BY ru.create_time DESC
    LIMIT 10

我们这里验证一下是否是这样
通过验证我们发现1.多秒就执行完了 原先需要20秒

早cpu高峰的时候
1 通过top命令找到那台机器连接我们的mysql比较耗CPU
2 通过 top -H -p PID 找到我们mysql那个物理进程比较耗费cpu
然后根据sql找到当时执行的sql或者是
找到我们的后台程序对应的数据库监控工具进行查询哪些比较慢
我的web后台使用到了druid 通过druid监控也可以查询到一些慢查询的sql

参考:https://www.isolves.com/it/sjk/MYSQL/2022-03-11/51075.html
http://www.muzhuangnet.com/show/44458.html
http://t.zoukankan.com/wyy123-p-9258513.html
https://blog.csdn.net/asd051377305/article/details/113979657

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/979526.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号