目錄
優化SQL的一般步驟
通過show status命令瞭解各種SQL的執行頻率
mysql> show status like 'Com_%';
通常比較關心以下幾個統計參數:
參數 | 說明 |
---|---|
Com_ select | 執行SELECT操作的次數, 一次查詢只累加1 |
Com_ insert | 執行INSERT操作的次數,對於批量插入的INSERT操作,只累加一次 |
Com_ update | 執行UPDATE操作的次數 |
Com_ delete | 執行DELETE操作的次數 |
Com_commit/Com_rollback | 事務提交和回滾的情況 |
...... | ....... |
定位執行效率較低的SQL語句
-
通過慢查詢日誌
在查詢結束以後才記錄,所以在應用反映執行效率出現問題的時候查詢慢查詢日誌並不能定位問題
-
通過
show processlist
查看當前MySQL在進行的線程,包括線程的狀態、是否鎖表等,可以實時地查看 SQL 的執行情況,同時對一些鎖表操作進行優化。
show profile的使用
-- 查看當前MySQL是否支持profile
mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES |
+------------------+
1 row in set, 1 warning (0.00 sec)
-- 默認是關閉的,可以通過set語句在session級別開啓
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)
-- 開啓profile
mysql> set profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
-- 再次查詢,已經開啓
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 1 |
+-------------+
1 row in set, 1 warning (0.00 sec)
執行show profiles,查看執行sql的query id
mysql> show profiles;
+----------+------------+--------------------+
| Query_ID | Duration | Query |
+----------+------------+--------------------+
| 1 | 0.00021675 | select @@profiling |
| 2 | 0.00007650 | show tables |
| 3 | 0.02193350 | show databases |
+----------+------------+--------------------+
3 rows in set, 1 warning (0.00 sec)
通過 show profile for query 語句能夠看到執行過程中線程的每個狀態和消耗的時間
mysql> show profile for query 3;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000069 |
| checking permissions | 0.000015 |
| Opening tables | 0.000056 |
| init | 0.000015 |
| System lock | 0.000008 |
| optimizing | 0.000008 |
| statistics | 0.000016 |
| preparing | 0.000016 |
| executing | 0.021611 |
| Sending data | 0.000036 |
| end | 0.000008 |
| query end | 0.000006 |
| closing tables | 0.000005 |
| removing tmp table | 0.000009 |
| closing tables | 0.000009 |
| freeing items | 0.000025 |
| cleaning up | 0.000021 |
+----------------------+----------+
17 rows in set, 1 warning (0.00 sec)
注意:
Sending data狀態表示MySQL線程開始訪問數據行並把結果返回給客戶端,而不僅僅是返回結果給客戶端。由於在Sending data狀態下,MySQL線程往往需要做大量的磁盤讀取操作,所以經常是整個查詢中耗時最長的狀態。
另外,還可以通過 tarce 進一步瞭解優化器選擇A執行計劃而不選擇B執行計劃,幫助我們更好地理解優化器的行爲。