Java慢查詢排查與性能調(diào)優(yōu)完整實(shí)戰(zhàn)指南
1. 事故全景:從告警到定位
1.1 事故時(shí)間線
timeline
title 故障時(shí)間軸
00:00 : 監(jiān)控系統(tǒng)首次告警
00:05 : 數(shù)據(jù)庫(kù)連接池使用率突破90%
00:08 : 網(wǎng)關(guān)開始出現(xiàn)503錯(cuò)誤
00:12 : 自動(dòng)擴(kuò)容觸發(fā)
00:15 : 人工介入排查1.2 關(guān)鍵指標(biāo)異常
| 指標(biāo) | 正常值 | 故障值 | 超出閾值 |
|---|---|---|---|
| 接口 | P99 | 響應(yīng)時(shí)間 | 200ms |
| 數(shù)據(jù)庫(kù) | QPS | 800 | 3500 |
| 活躍連接數(shù) | 20 | 200(max) | 10x |
1.3 排查工具鏈
// 監(jiān)控工具清單
public class TroubleshootingTools {
String[] tools = {
"SkyWalking 8.7.0",
"Arthas 3.6.7",
"Prometheus + Grafana",
"MySQL Slow Query Log"
};
}
2. 深度剖析:MySQL 分頁(yè)查詢的致命陷阱
2.1 Offset 分頁(yè)的執(zhí)行原理

??性能消耗公式??:
總成本 = 全表掃描成本 + 排序成本 + 跳過(guò)行成本
2.2 索引失效的根本原因
-- 問(wèn)題SQL示例 EXPLAIN SELECT * FROM member_info WHERE status = 1 ORDER BY create_time DESC LIMIT 10000, 20;
??執(zhí)行計(jì)劃關(guān)鍵解讀??:
- type: ALL:全表掃描
- rows: 1250000:掃描行數(shù)
- Extra: Using filesort:無(wú)法利用索引排序
2.3 深度優(yōu)化方案對(duì)比
方案一:游標(biāo)分頁(yè)(推薦)
-- 優(yōu)化后SQL(基于ID分頁(yè))
SELECT * FROM member_info
WHERE status = 1 AND id > #{lastId}
ORDER BY id ASC
LIMIT 20;
方案二:覆蓋索引優(yōu)化
-- 新增復(fù)合索引 ALTER TABLE member_info ADD INDEX idx_status_createtime (status, create_time); -- 改寫SQL SELECT * FROM member_info WHERE status = 1 ORDER BY create_time DESC LIMIT 20;
方案對(duì)比表
| 方案 | 掃描行數(shù) | 排序方式 | 適用場(chǎng)景 |
|---|---|---|---|
| 原始Offset | 10020 | 文件排序 | 小數(shù)據(jù)量 |
| 游標(biāo)分頁(yè) | 20 | 索引排序 | 大數(shù)據(jù)量、深度分頁(yè) |
| 覆蓋索引 | 20 | 索引覆蓋 | 中等數(shù)據(jù)量 |
3. 完整優(yōu)化實(shí)戰(zhàn)
3.1 MyBatis 改造示例
public interface MemberMapper {
// 舊方法(問(wèn)題代碼)
@Select("SELECT * FROM member_info WHERE status = #{status} LIMIT #{offset}, #{limit}")
List<Member> listByPage(@Param("status") int status,
@Param("offset") int offset,
@Param("limit") int limit);
// 新方法(優(yōu)化后)
@Select("SELECT * FROM member_info WHERE status = #{status} AND id > #{lastId} ORDER BY id ASC LIMIT #{limit}")
List<Member> listByCursor(@Param("status") int status,
@Param("lastId") long lastId,
@Param("limit") int limit);
}
3.2 服務(wù)層改造
public PageResult<Member> getMemberList(int pageSize, Long lastId) {
// 游標(biāo)分頁(yè)查詢
List<Member> members = memberMapper.listByCursor(1, lastId, pageSize);
// 獲取下一頁(yè)的游標(biāo)
Long nextLastId = members.isEmpty() ? null : members.get(members.size()-1).getId();
return new PageResult<>(members, nextLastId);
}
4. 防御體系:慢查詢防控全景方案
4.1 事前預(yù)防

4.2 事中監(jiān)控
# my.cnf 慢查詢配置 slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 1 log_queries_not_using_indexes = 1
5. 優(yōu)化效果驗(yàn)證
5.1 壓測(cè)數(shù)據(jù)對(duì)比
| 場(chǎng)景 | TPS | 平均響應(yīng)時(shí)間 | 錯(cuò)誤率 | CPU使用率 |
|---|---|---|---|---|
| 優(yōu)化前 | 85 | 6100ms | 32% | 96% |
| 優(yōu)化后 | 2150 | 230ms | 0% | 45% |
6. 工程師的自我修養(yǎng)
6.1 SQL 編寫軍規(guī)
- ??禁止?? 無(wú)限制的 SELECT * ??
- 必須?? 為分頁(yè)查詢添加 ORDER BY ??
- 推薦?? 使用游標(biāo)替代 OFFSET
- ??強(qiáng)制?? 為 WHERE 條件字段建立索引
總結(jié)
到此這篇關(guān)于Java慢查詢排查與性能調(diào)優(yōu)的文章就介紹到這了,更多相關(guān)Java慢查詢排查與性能調(diào)優(yōu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot啟動(dòng)feign項(xiàng)目報(bào)錯(cuò):Service id not legal hostnam的解決
這篇文章主要介紹了springboot啟動(dòng)feign項(xiàng)目報(bào)錯(cuò):Service id not legal hostnam的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
一文學(xué)會(huì)如何在SpringBoot中使用線程池執(zhí)行定時(shí)任務(wù)
在開發(fā)現(xiàn)代應(yīng)用程序時(shí),定時(shí)任務(wù)是一項(xiàng)常見(jiàn)的需求,SpringBoot提供了一個(gè)強(qiáng)大的定時(shí)任務(wù)框架,可以輕松地執(zhí)行各種定時(shí)任務(wù),結(jié)合線程池的使用,可以更好地管理任務(wù)的執(zhí)行,提高系統(tǒng)的性能和穩(wěn)定性,本文將介紹如何在Spring Boot中使用線程池執(zhí)行定時(shí)任務(wù)2023-06-06
Springboot實(shí)現(xiàn)高吞吐量異步處理詳解(適用于高并發(fā)場(chǎng)景)
這篇文章主要介紹了Springboot實(shí)現(xiàn)高吞吐量異步處理詳解(適用于高并發(fā)場(chǎng)景),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
教你怎么在IDEA中創(chuàng)建java多模塊項(xiàng)目
這篇文章主要介紹了教你怎么在IDEA中創(chuàng)建java多模塊項(xiàng)目,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
常用Maven庫(kù),鏡像庫(kù)及maven/gradle配置(小結(jié))
這篇文章主要介紹了常用Maven庫(kù),鏡像庫(kù)及maven/gradle配置(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Spring使用@Autowired注解靜態(tài)實(shí)例對(duì)象方式
這篇文章主要介紹了Spring使用@Autowired注解靜態(tài)實(shí)例對(duì)象方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Java如何使用正則表達(dá)式從字符串中提取數(shù)字
這篇文章主要介紹了Java如何使用正則表達(dá)式從字符串中提取數(shù)字問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

