SHOW PROFILE 是 MySQL 會話級的性能剖析工具,能精確展示 SQL 執行各階段的耗時、CPU、I/O、上下文切換等資源消耗,是定位慢查詢瓶頸、驗證優化效果的利器。本文詳解開啟方法、輸出解讀、進階參數、實戰案例與局限性。
-- 1. 當前會話開啟剖析
SET profiling = 1;
-- 或
SET SESSION profiling = 1;
-- 2. 執行目標查詢
SELECT COUNT(DISTINCT actor.first_name) AS cnt_name, COUNT(*) AS cnt
FROM sakila.film_actor
INNER JOIN sakila.actor USING (actor_id)
GROUP BY sakila.film_actor.film_id
ORDER BY cnt_name DESC;
-- 3. 查看剖析記錄列表
SHOW PROFILES;
-- 輸出:Query_ID, Duration, Query 文本
-- 4. 查看指定 Query_ID 詳細剖析
SHOW PROFILE FOR QUERY 1;
-- 默認顯示 Status(階段)和 Duration(秒)
典型輸出階段及含義:
| 階段 | 含義 | 關注點 |
|---|---|---|
| starting | 查詢開始初始化 | - |
| checking permissions | 權限檢查 | - |
| Opening tables | 打開表、獲取元數據 | 表數量多時耗時 |
| System lock / Table lock | 系統/表級鎖 | 並發衝突信號 |
| init / optimizing / statistics / preparing | 優化器階段:初始化、優化、統計信息、準備 | 複雜查詢優化耗時 |
| Creating tmp table | 創建內部臨時表 | 避免臨時表是優化關鍵 |
| executing | 執行查詢計劃 | - |
| Copying to tmp table / Copying to group table | 數據拷貝到臨時表/分組表 | 大數據量分組/排序瓶頸 |
| Creating sort index | 創建排序索引 | ORDER BY 無索引時出現 |
| Sorting result | 結果排序 | - |
| Sending data | 發送結果給客戶端 | 網絡/結果集大小影響 |
| end / query end / closing tables / freeing items / cleaning up | 收尾階段 | - |
-- CPU 時間(用戶態/內核態)
SHOW PROFILE CPU FOR QUERY 1;
-- 塊 I/O 操作
SHOW PROFILE BLOCK IO FOR QUERY 1;
-- 上下文切換
SHOW PROFILE CONTEXT SWITCHES FOR QUERY 1;
-- IPC 消息
SHOW PROFILE IPC FOR QUERY 1;
-- 頁錯誤
SHOW PROFILE PAGE FAULTS FOR QUERY 1;
-- 源碼函數定位(需 debug 構建)
SHOW PROFILE SOURCE FOR QUERY 1;
-- 所有維度
SHOW PROFILE ALL FOR QUERY 1;
+------------------------------+-----------+----------+------------+
| Status | Duration | CPU_user | CPU_system |
+------------------------------+-----------+----------+------------+
| starting | 0.000183 | 0.000000 | 0.000000 |
| ... | ... | ... | ... |
| rename result table | 70.364027 | 7.470864 | 41.612674 | -- 高 CPU 系統態:內核操作(如文件重命名、鎖)
| ... | ... | ... | ... |
+------------------------------+-----------+----------+------------+
SET profiling = 1;
-- 第一次查詢:未命中緩存
SELECT COUNT(1) AS cnt FROM tran_excution; -- 0.003875s
-- 第二次查詢:命中緩存
SELECT COUNT(1) AS cnt FROM tran_excution; -- 0.000036s
SHOW PROFILE SOURCE FOR QUERY 1; -- 未命中
SHOW PROFILE SOURCE FOR QUERY 2; -- 命中
| executing | 0.000015 | exec | sql_select.cc | 1836 |
| Sending data | 0.003875 | exec | sql_select.cc | 2380 | -- 核心耗時
| storing result in query cache | 0.000017 | end_of_result | sql_cache.cc | 1020 |
| checking query cache for query | 0.000016 | send_result_to_client | sql_cache.cc | 1561 |
| sending cached result to clien | 0.000036 | send_result_to_client | sql_cache.cc | 1749 | -- 直接返回,跳過執行引擎
| logging slow query | 0.000017 | log_slow_statement | sql_parse.cc | 1461 |
結論:緩存命中跳過 executing、Sending data 等核心引擎階段,耗時降低 **100 倍**。但緩存適用性需評估:寫入頻繁、大結果集、分區表等場景可能得不償失。
| 項目 | 說明 |
|---|---|
| 作用域 | 僅當前會話(SESSION),無法分析其他連接 |
| 歷史記錄數 | profiling_history_size(默認 15,最大 100,設 0 關閉) |
| 自身開銷 | 剖析過程消耗 CPU/內存,生產環境慎用,建議測試環境複現 |
| 信息_schema 等價 | SELECT * FROM information_schema.profiling WHERE query_id = 1 ORDER BY seq; |
| 版本支持 | MySQL 5.0.37+ 引入,5.6/5.7/8.0 均支持 |
| 替代方案 | EXPLAIN ANALYZE (8.0.18+)、PERFORMANCE_SCHEMA、sys.schema、pt-query-digest 分析慢查詢日志 |
SHOW PROCESSLIST / APM)SET profiling=1Query_IDSHOW PROFILE CPU, BLOCK IO FOR QUERY id 定位高消耗階段EXPLAIN 分析執行計劃,針對性優化(索引、SQL改寫、配置調整)Duration、CPU、Tmp table 等指標SHOW PROFILE 提供**微秒級、階段級、多維度**的執行剖析,是「看得見」SQL 執行內幕的顯微鏡Creating tmp table、Copying to group table、Sorting result 等優化痛點PERFORMANCE_SCHEMA + sys.schema + 慢查詢日志分析PROFILE,讓優化從「憑感覺」變為「憑數據」