MySQL 內建的 Profiling 是剖析 SQL 執行全生命週期資源消耗的利器。本文通過實測對比「首次查詢」與「緩存命中查詢」的執行細節,演示如何用 Profiling 診斷效能問題。
SELECT @@profiling; -- 預設 0 (關閉)
SET profiling = 1; -- 開啟
SELECT @@profiling; -- 確認 1 (開啟)
CREATE TABLE t_engines SELECT * FROM t_engines1; -- 耗時 0.10 秒
SELECT COUNT(*) FROM t_engines; -- Query_ID 27
SELECT COUNT(*) FROM t_engines; -- Query_ID 28 (命中查詢緩存)
SHOW PROFILES; -- 列出近期查詢及耗時
結果摘要:
+----------+------------+-------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------------+
| 26 | 0.10213775 | create table t_engines select * from t_engines1 |
| 27 | 0.00032775 | select count(*) from t_engines |
| 28 | 0.00003850 | select count(*) from t_engines |
+----------+------------+-------------------------------------------------+
SHOW PROFILE FOR QUERY 27;
+--------------------------------+------------+
| Status | Duration |
+--------------------------------+------------+
| (initialization) | 0.00000425 |
| checking query cache for query | 0.00004050 |
| checking permissions | 0.00001050 |
| Opening tables | 0.00018250 |
| System lock | 0.00000450 |
| Table lock | 0.00001775 |
| init | 0.00001075 |
| optimizing | 0.00000550 |
| executing | 0.00002775 |
| end | 0.00000450 |
| query end | 0.00000325 |
| storing result in query cache | 0.00000400 |
| freeing items | 0.00000400 |
| closing tables | 0.00000500 |
| logging slow query | 0.00000300 |
+--------------------------------+------------+
關鍵階段:Opening tables、Table lock 等物理 I/O 操作耗時佔大頭。
SHOW PROFILE FOR QUERY 28;
+-------------------------------------+------------+
| Status | Duration |
+-------------------------------------+------------+
| (initialization) | 0.00000350 |
| checking query cache for query | 0.00000750 |
| checking privileges on cached query | 0.00000500 |
| checking permissions | 0.00000525 |
| sending cached result to client | 0.00001275 |
| logging slow query | 0.00000450 |
+-------------------------------------+------------+
僅 6 個步驟,核心是 sending cached result to client,總耗時 0.000039 秒,約為首次查詢的 1/8。
SELECT SUM(FORMAT(DURATION,6)) AS DURATION
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = 27 ORDER BY SEQ; -- 0.000326
SELECT SUM(FORMAT(DURATION,6)) AS DURATION
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = 28 ORDER BY SEQ; -- 0.000039
Opening tables、filesort、tmp table 等慢速操作SHOW PROFILE,建議遷移至 Performance Schema。Profiling 讓 SQL 效能優化從「猜測」變為「數據驅動」,是 DBA 與開發者的必備技能。