MySQL慢查詢(xún)?nèi)罩镜膶?shí)現(xiàn)
一、慢查詢(xún)?nèi)罩臼鞘裁矗?/h2>
慢查詢(xún)?nèi)罩揪褪?MySQL 的SQL性能記錄儀,專(zhuān)門(mén)自動(dòng)記錄數(shù)據(jù)庫(kù)里執(zhí)行卡頓、性能差的SQL。
?? 注意:慢日志只是被動(dòng)記錄,不會(huì)阻止SQL執(zhí)行,不影響業(yè)務(wù)運(yùn)行。
作用:線上項(xiàng)目CPU飆升、接口超時(shí)、頁(yè)面加載慢,第一時(shí)間靠慢日志找到問(wèn)題SQL,是運(yùn)維和開(kāi)發(fā)必備排障工具。
慢日志的記錄機(jī)制(核心邏輯,必須理解)
慢日志的默認(rèn)記錄條件只有一個(gè):執(zhí)行時(shí)間 > long_query_time 閾值。
log_queries_not_using_indexes 是額外的附加開(kāi)關(guān),開(kāi)啟后,無(wú)索引的SQL即使不超時(shí)也會(huì)被記錄。
兩者是**"或"**的關(guān)系——滿足任一條件即被記錄:
| 條件 | 是否記錄 |
|---|---|
| 執(zhí)行時(shí)間 > 閾值 | ? 記錄 |
| 執(zhí)行時(shí)間 ≤ 閾值,但無(wú)索引 + 開(kāi)啟了無(wú)索引記錄 | ? 記錄 |
| 執(zhí)行時(shí)間 ≤ 閾值,且無(wú)索引記錄未開(kāi)啟 | ? 不記錄 |
所以:全表掃描 ≠ 慢查詢(xún)。小表全表掃描可能只需0.01秒,低于閾值就不會(huì)被記錄(除非開(kāi)了無(wú)索引記錄)。
二、新手最大誤區(qū):線上慢日志要不要關(guān)閉?(面試必考)
核心結(jié)論:線上慢日志總開(kāi)關(guān)必須永久開(kāi)啟,絕對(duì)不能關(guān)閉!
小白誤區(qū)糾正
很多人覺(jué)得開(kāi)慢日志占用性能,其實(shí)完全不用擔(dān)心:
- 慢日志的寫(xiě)入是追加式IO,對(duì)性能影響極?。ㄍǔ?< 1%)
- 真正影響性能的是問(wèn)題SQL本身,不是記錄問(wèn)題SQL的日志
真實(shí)規(guī)范
關(guān)閉慢日志是重大隱患——線上出故障時(shí)無(wú)日志可排查,無(wú)法定位問(wèn)題根源。
線上正確做法
不關(guān)閉開(kāi)關(guān),只調(diào)優(yōu)參數(shù):調(diào)高耗時(shí)閾值、關(guān)閉無(wú)索引SQL記錄,避免日志爆炸。
三、核心配置參數(shù)(零基礎(chǔ)必懂)
查詢(xún)所有慢日志參數(shù)命令:SHOW VARIABLES LIKE 'slow_query%';
3.1 三大必備參數(shù)
| 參數(shù) | 含義 | 推薦值 |
|---|---|---|
| slow_query_log | 慢日志總開(kāi)關(guān) | 線上永久 ON |
| long_query_time | 慢查詢(xún)判定閾值(單位:秒) | 開(kāi)發(fā):0.1秒 / 線上:1~2秒 |
| log_queries_not_using_indexes | 是否記錄無(wú)索引全表掃描SQL | 開(kāi)發(fā):ON / 線上:OFF |
閾值說(shuō)明:
- 開(kāi)發(fā)環(huán)境設(shè) 0.1秒(嚴(yán)格排查,提前揪隱患),極端場(chǎng)景可設(shè) 0秒 記錄所有SQL
- 線上環(huán)境設(shè) 1~2秒(只記錄真正卡頓的SQL)
3.2 進(jìn)階參數(shù)(線上必配)
| 參數(shù) | 含義 | 推薦值 |
|---|---|---|
| slow_query_log_file | 日志文件存儲(chǔ)路徑 | 確保有磁盤(pán)空間,路徑可訪問(wèn) |
| min_examined_row_limit | 最少掃描行數(shù)閾值 | 100~1000,過(guò)濾小表噪音 |
| log_output | 日志輸出方式 | FILE(默認(rèn))/ TABLE |
min_examined_row_limit 配合無(wú)索引記錄使用:即使開(kāi)了 log_queries_not_using_indexes,掃描行數(shù)低于此值的SQL也不會(huì)被記錄,有效減少小表無(wú)效日志。
3.3 動(dòng)態(tài)修改參數(shù)(不停機(jī)生效)
線上不想重啟MySQL時(shí),可以用動(dòng)態(tài)命令:
-- 臨時(shí)開(kāi)啟慢日志(重啟后失效) SET GLOBAL slow_query_log = ON; -- 臨時(shí)調(diào)整閾值 SET GLOBAL long_query_time = 2; -- 永久生效需同時(shí)修改 my.cnf 配置文件
?? long_query_time 修改后,需要新連接才生效,已有連接仍用舊值。
四、實(shí)操疑難問(wèn)題全解
問(wèn)題1:為什么同樣是全表掃描,有的進(jìn)慢日志、有的不進(jìn)?
核心規(guī)則:慢日志默認(rèn)只看耗時(shí),不看是否全表掃描。
全表掃描 ≠ 慢查詢(xún)!你的4000行小表,全表掃描僅需0.03秒,低于閾值,所以不記錄;數(shù)據(jù)量過(guò)10萬(wàn)后,耗時(shí)暴漲超過(guò)閾值,立刻被記錄。
如果開(kāi)了 log_queries_not_using_indexes,則無(wú)索引SQL不超時(shí)也會(huì)被記錄——但小表可以用 min_examined_row_limit 過(guò)濾掉。
問(wèn)題2:LIKE '王%' 前綴模糊查詢(xún),到底進(jìn)不進(jìn)慢日志?
答案取決于列上是否有索引,不存在所謂的"隱性?xún)?yōu)化規(guī)則":
| 場(chǎng)景 | 執(zhí)行方式 | 是否被記錄 |
|---|---|---|
| 列有索引 + LIKE '王%' | 索引范圍掃描(不是全表掃描) | 不觸發(fā)無(wú)索引記錄;超時(shí)才記錄 |
| 列無(wú)索引 + LIKE '王%' | 全表掃描 | 開(kāi)了無(wú)索引記錄就記錄,超時(shí)也記錄 |
| LIKE '%王' 左模糊 | 無(wú)論有無(wú)索引,都無(wú)法走索引范圍掃描 | 全表掃描,開(kāi)了無(wú)索引記錄就記錄 |
對(duì)比記憶:LIKE '王%' 有索引時(shí)能走范圍掃描,不是全表掃描;LIKE '%王' 左模糊無(wú)法利用B+樹(shù)索引有序性,一定全表掃描。
問(wèn)題3:為什么xuesheng_yizizhu > 100全表掃描會(huì)被記錄?
這條SQL掃描全表4400行、返回4300+行,被記錄有兩個(gè)可能原因:
- 如果開(kāi)了 log_queries_not_using_indexes:沒(méi)有索引 = 滿足無(wú)索引記錄條件,直接被記錄,跟掃描行數(shù)多少無(wú)關(guān)
- 如果沒(méi)開(kāi)無(wú)索引記錄:那就是執(zhí)行耗時(shí)超過(guò)了 long_query_time 閾值,被耗時(shí)規(guī)則捕獲
判斷 掃描行數(shù) >> 返回行數(shù) 是索引缺失的信號(hào),但這不是慢日志記錄的原因,而是需要優(yōu)化的原因。
五、慢日志核心字段(小白秒懂看日志)
拿到慢日志,不用看雜亂內(nèi)容,只看這4個(gè)字段就能定位問(wèn)題:
| 字段 | 含義 | 問(wèn)題判斷 |
|---|---|---|
| Query_time | SQL總執(zhí)行耗時(shí) | 核心判斷依據(jù),數(shù)值大 = SQL本身慢 |
| Lock_time | 鎖等待耗時(shí) | 數(shù)值高是鎖競(jìng)爭(zhēng)問(wèn)題,不是SQL本身慢 |
| Rows_examined | 實(shí)際掃描行數(shù) | 風(fēng)險(xiǎn)核心,數(shù)值大 = 可能在全表掃描 |
| Rows_sent | 最終返回的行數(shù) | 用于和掃描行數(shù)對(duì)比 |
萬(wàn)能判斷口訣:Rows_examined ? Rows_sent(掃描行數(shù)遠(yuǎn)大于返回行數(shù))= 索引缺失/索引失效,必須優(yōu)化
典型場(chǎng)景速判:
| 現(xiàn)象 | 診斷 |
|---|---|
| Query_time大,Lock_time小 | SQL本身慢,需要優(yōu)化索引或改寫(xiě)SQL |
| Query_time大,Lock_time大 | 鎖競(jìng)爭(zhēng)嚴(yán)重,需要優(yōu)化事務(wù)/鎖粒度 |
| Rows_examined >> Rows_sent | 索引缺失或失效,補(bǔ)索引或改寫(xiě)SQL |
| Rows_examined ≈ Rows_sent | 掃描行都是需要的,考慮是否業(yè)務(wù)需求合理 |
六、三種環(huán)境查看慢日志的方法(全覆蓋)
6.1 本地PHPStudy環(huán)境
直接找到 slow.log 文件,用編輯器打開(kāi),直觀查看原始日志,適合本地調(diào)試。
6.2 線上Linux服務(wù)器(企業(yè)常用)
方法一:mysqldumpslow(MySQL自帶,簡(jiǎn)單快捷)
自動(dòng)合并重復(fù)SQL、排序統(tǒng)計(jì),解決日志雜亂問(wèn)題。
常用命令:
# 查耗時(shí)最長(zhǎng)Top10 mysqldumpslow -s t -t 10 /var/log/mysql/slow.log # 查執(zhí)行次數(shù)最多Top10 mysqldumpslow -s c -t 10 /var/log/mysql/slow.log # 查平均耗時(shí)最長(zhǎng)Top10 mysqldumpslow -s at -t 10 /var/log/mysql/slow.log
?? mysqldumpslow 只能分析 FILE 格式的日志,如果 log_output=TABLE 則無(wú)法使用,需用 SELECT * FROM mysql.slow_log 查詢(xún)。
方法二:pt-query-digest(Percona Toolkit,企業(yè)主流)
比 mysqldumpslow 強(qiáng)大得多,是實(shí)際運(yùn)維最常用的分析工具:
# 分析慢日志,輸出完整報(bào)告 pt-query-digest /var/log/mysql/slow.log # 只分析最近1小時(shí)的慢查詢(xún) pt-query-digest --since '1h' /var/log/mysql/slow.log # 將結(jié)果保存到數(shù)據(jù)庫(kù) pt-query-digest --review h=host,D=db,t=review /var/log/mysql/slow.log
6.3 阿里云/火山RDS云數(shù)據(jù)庫(kù)
無(wú)服務(wù)器權(quán)限,直接控制臺(tái)操作:實(shí)例詳情 → 日志管理 → 慢查詢(xún)?nèi)罩?,支持篩選、導(dǎo)出、一鍵分析。
七、日志自動(dòng)切割方案(線上必配)
線上慢日志會(huì)持續(xù)增長(zhǎng),必須配置自動(dòng)切割,避免單文件過(guò)大占滿磁盤(pán)。
方案一:logrotate(Linux系統(tǒng)自帶)
創(chuàng)建配置文件 /etc/logrotate.d/mysql-slow:
/var/log/mysql/slow.log {
daily
rotate 30
missingok
compress
delaycompress
notifempty
create 640 mysql mysql
postrotate
# 通知MySQL重新打開(kāi)日志文件
mysql -e "SELECT 1" >/dev/null 2>&1 || true
endscript
}方案二:手動(dòng) mv + flush(簡(jiǎn)單直接)
# 1. 重命名當(dāng)前日志 mv /var/log/mysql/slow.log /var/log/mysql/slow.log.bak # 2. 刷新MySQL日志句柄(MySQL自動(dòng)創(chuàng)建新文件) mysql -e "FLUSH SLOW LOGS;"
八、開(kāi)發(fā)+線上落地規(guī)范(工作必守)
開(kāi)發(fā)環(huán)境規(guī)范
- 開(kāi)啟慢日志 + 低耗時(shí)閾值(0.1秒)+ 記錄無(wú)索引SQL
- 上線前清零所有全表掃描、慢查詢(xún)SQL,提前規(guī)避線上風(fēng)險(xiǎn)
- 極端排查場(chǎng)景可設(shè) long_query_time=0 記錄所有SQL
線上生產(chǎn)環(huán)境規(guī)范
- 慢日志總開(kāi)關(guān)永久開(kāi)啟,禁止關(guān)閉
- 關(guān)閉無(wú)索引SQL記錄,防止海量日志占滿磁盤(pán)
- 配置 min_examined_row_limit,即使臨時(shí)開(kāi)啟無(wú)索引記錄也能過(guò)濾小表噪音
- 配置日志自動(dòng)切割,避免單文件過(guò)大
- 避免無(wú)條件全表查詢(xún),避免左模糊/全模糊查詢(xún) %xxx,業(yè)務(wù)需要時(shí)用ES/搜索引擎替代
- 設(shè)置合理的 long_query_time(1~2秒),太低日志爆炸,太高漏掉問(wèn)題
九、企業(yè)標(biāo)準(zhǔn)SQL優(yōu)化流程(面試必背)
固定流程:慢日志抓取問(wèn)題SQL → EXPLAIN分析執(zhí)行計(jì)劃 → 補(bǔ)索引/改寫(xiě)SQL → 復(fù)測(cè)性能
這是業(yè)界最常用的數(shù)據(jù)庫(kù)性能排查標(biāo)準(zhǔn)流程,適用于絕大多數(shù)卡頓問(wèn)題的定位和解決。
發(fā)現(xiàn)問(wèn)題 → 慢日志抓SQL → EXPLAIN分析 → 優(yōu)化方案 → 上線復(fù)測(cè) ↑ | └────────────── 未解決則循環(huán) ←───────────────────────┘
十、面試速記卡(必背)
| # | 核心要點(diǎn) | 一句話記憶 |
|---|---|---|
| 1 | 慢日志記錄條件 | 耗時(shí)超閾值 或 無(wú)索引(需開(kāi)啟),兩者是"或"關(guān)系 |
| 2 | 線上核心規(guī)范 | 慢日志永久開(kāi)啟,關(guān)閉無(wú)索引記錄,調(diào)高耗時(shí)閾值 |
| 3 | 全表掃描 ≠ 慢查詢(xún) | 小表全表掃描可能很快,不會(huì)觸發(fā)耗時(shí)記錄 |
| 4 | 模糊查詢(xún)索引問(wèn)題 | LIKE '王%' 有索引走范圍掃描,LIKE '%王' 一定全表掃描 |
| 5 | 問(wèn)題判斷核心 | 掃描行數(shù)遠(yuǎn)大于返回行數(shù) = 需要優(yōu)化索引 |
| 6 | 優(yōu)化固定流程 | 抓慢SQL → EXPLAIN分析 → 優(yōu)化SQL/索引 → 復(fù)測(cè) |
| 7 | 動(dòng)態(tài)修改 | SET GLOBAL 可不停機(jī)修改,但 long_query_time 需新連接才生效 |
到此這篇關(guān)于MySQL慢查詢(xún)?nèi)罩镜膶?shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL慢查詢(xún)?nèi)罩緝?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 從配置到性能優(yōu)化全面解析MySQL慢查詢(xún)?nèi)罩?/a>
- MySQL慢查詢(xún)?nèi)罩緩呐渲玫絻?yōu)化實(shí)踐全解析
- 一文帶大家深入了解下MySQL中的慢查詢(xún)?nèi)罩?/a>
- MySQL日志系統(tǒng)之錯(cuò)誤日志、慢查詢(xún)?nèi)罩尽⒍M(jìn)制日志詳解
- MySQL慢查詢(xún)?nèi)罩?Slow Query Log)的實(shí)現(xiàn)
- MySQL慢查詢(xún)?nèi)罩驹斀馀c性能優(yōu)化指南(總結(jié))
- MySQL慢查詢(xún)?nèi)罩緎lowlog的具體使用
- 詳解MySQL的慢查詢(xún)?nèi)罩竞湾e(cuò)誤日志
- 怎樣快速開(kāi)啟MySQL的慢查詢(xún)?nèi)罩?/a>
- MySQL通用查詢(xún)?nèi)罩竞吐樵?xún)?nèi)罩救娣治?/a>
相關(guān)文章
mysql搭建主從復(fù)制的實(shí)現(xiàn)步驟
在MySQL集群中,主庫(kù)更新會(huì)同步到從庫(kù),但從庫(kù)更新不同步到主庫(kù),主從復(fù)制能分?jǐn)倝毫?本文就來(lái)介紹一下mysql搭建主從復(fù)制的實(shí)現(xiàn)步驟,感興趣的可以了解一下2024-11-11
MySQL中LIKE運(yùn)算符的多種使用方式及示例演示
無(wú)論是簡(jiǎn)單的模式匹配還是復(fù)雜的模式匹配,LIKE運(yùn)算符都提供了強(qiáng)大的功能來(lái)滿足不同的匹配需求,通過(guò)本文的介紹,我們?cè)敿?xì)了解了在MySQL數(shù)據(jù)庫(kù)中使用LIKE運(yùn)算符進(jìn)行模糊匹配的多種方式,感興趣的朋友跟隨小編一起看看吧2023-07-07
MySQL中萬(wàn)能備份腳本的實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了MySQL中萬(wàn)能備份腳本的實(shí)現(xiàn)方法,此腳本適用于 MySQL 各個(gè)生命周期的版本,文中的示例代碼講解詳細(xì),有需要的可以了解下2025-11-11
MySQL?優(yōu)化利器?SHOW?PROFILE?的實(shí)現(xiàn)原理及細(xì)節(jié)展示
這篇文章主要介紹了MySQL優(yōu)化利器SHOW?PROFILE的實(shí)現(xiàn)原理,通過(guò)實(shí)例代碼展示SHOW PROFILE的用法,需要的朋友可以參考下2024-12-12
MySQL數(shù)據(jù)庫(kù)跨版本遷移的實(shí)現(xiàn)三種方式
本文主要介紹了MySQL數(shù)據(jù)庫(kù)跨版本遷移的實(shí)現(xiàn),主要包含mysqldump,物理文件遷移和原地升級(jí)三種,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
如何解決mysql無(wú)法關(guān)閉的問(wèn)題
在本篇文章里小編給大家整理的是一篇關(guān)于解決mysql無(wú)法關(guān)閉的問(wèn)題的相關(guān)內(nèi)容,需要的朋友們可以參考下。2020-08-08

