MySQL 5.0.37+ 引入的 PROFILING 功能,是一個會話級的 SQL 執行性能剖析工具。它能將一條查詢在 Server 層與存儲引擎層的各階段耗時、CPU 消耗、上下文切換、塊 I/O 等指標逐行記錄,是定位慢查詢瓶頸、理解執行路徑的利器。
-- 1. 開啟 profiling(僅對當前會話生效)
SET profiling = 1;
-- 2. 執行目標查詢(含錯誤查詢也會記錄)
SELECT * FROM `user` LIMIT 1;
SELECT COUNT(*) FROM `user` GROUP BY `sex`;
-- 3. 查看彙總列表
SHOW PROFILES;
輸出示例:
| Query_ID | Duration | Query |
|---|---|---|
| 1 | 0.000132 | SELECT DATABASE() |
| 2 | 0.000441 | select * from user limit 2 |
| 3 | 1.955441 | select nick,count(*) from user group by online |
SHOW PROFILE CPU, BLOCK IO FOR QUERY 3;
關鍵欄位說明:
starting、Opening tables、System lock、Table lock、optimizing、statistics、Creating tmp table、Copying to tmp table、Sorting result、Sending data 等)。上例中 Copying to tmp table 耗時 1.9 秒、佔用大量 CPU 與 Block I/O,提示 GROUP BY 觸發了內部臨時表與文件排序——優化方向可考慮增加覆蓋索引或調整 tmp_table_size。
| 語法 | 適用場景 |
|---|---|
SHOW PROFILE FOR QUERY n; | 基礎耗時分布 |
SHOW PROFILE CPU, MEMORY FOR QUERY n; | CPU 與內存分配分析 |
SHOW PROFILE BLOCK IO, CONTEXT SWITCHES FOR QUERY n; | I/O 瓶頸與上下文切換 |
SHOW PROFILE ALL FOR QUERY n; | 全維度輸出(資訊最全但較繁雜) |
SET profiling=1 僅影響當前連線,斷開連線或 SET profiling=0 即清空記錄,不影響其他會話。profiling_history_size 變量調整(最大 1000)。某查詢 SELECT * FROM orders WHERE status=1 AND created_at > '2023-01-01' 耗時 2.3 秒。Profiling 顯示 Sending data 階段佔 95% 時間,Block_ops_in 極高。EXPLAIN 確認 type=ALL。加上聯合索引 idx_status_created(status, created_at) 後,Profiling 顯示 Sending data 降至 0.02 秒,Block_ops_in 歸零,性能提升百倍。
MySQL Profiling 雖屬舊版功能(MySQL 8.0 標記為 deprecated,建議遷移至 Performance Schema),但在大量存量 5.6/5.7 環境中仍是不可或缺的「手術刀」。熟練掌握其輸出解讀,能讓你從「感覺慢」進化到「精準定位慢在哪、為什麼慢、怎麼改」,是每位 DBA 與後端工程師的必修技能。