赞
踩
top
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;
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。