記錄慢查詢
- 開啟慢查詢的配置
- 查看慢查詢狀態
- 動態開啟慢查詢日志
- 永久開啟配置
- log_throttle_queries_not_using_indexes
- 記錄慢查詢對性能的影響
- 實際案例說明
- 第一條記錄
- 第二條記錄
- 第三條記錄
- 第四條記錄
開啟慢查詢的配置
查看慢查詢狀態
- 執行 `show variables like 'slow_query_log%';`,
- 查看 `slow_query_log` 是否為 `ON`,若為 `OFF` 則未開啟
- 查看慢查詢日志文件路徑
動態開啟慢查詢日志
- 執行
set global slow_query_log='ON';
可動態開啟慢查詢日志,但數據庫重啟后會失效
永久開啟配置
-
修改
my.cnf
或my.ini
,在[mysqld]
部分添加參數 說明 slow_query_log on :開啟 slow_query_log_file 記錄慢sql日志路徑 long_query_time 默認為 10 秒,查詢耗時超過該閾值的 SQL 語句會被記錄 log_queries_not_using_indexes on : 查詢sql沒有使用索引,會記錄到慢查詢日志中 log_throttle_queries_not_using_indexes = 5 每分鐘最多記錄 5 次未使用索引的查詢 log_slow_slave_statements min_examined_row_limit 掃描行數超過 100 行的查詢才會被記錄為慢查詢 ```sqlslow_query_log = on slow_query_log_file = /u01/soft/oracle/logs/mysqld_slow.log long_query_time = 2log_queries_not_using_indexes = onlog_throttle_queries_not_using_indexes = 5log_slow_slave_statements = 1min_examined_row_limit = 100```
- 保存后重啟 MySQL 服務使配置生效
log_throttle_queries_not_using_indexes
- 不是只記錄 5 次,而是每分鐘最多記錄 5 次未使用索引的查詢。
-
設置目的
- 這個參數主要是為了防止慢查詢日志文件被大量未使用索引的查詢信息瞬間淹沒。因為在實際的應用場景中,可能會有一些頻繁執行但未使用索引的查詢語句,如果不加以限制,這些語句的日志記錄會迅速占據大量的存儲空間,使得日志文件變得臃腫,不方便對真正有價值的慢查詢信息進行分析。
-
工作原理
- 當開啟
log_queries_not_using_indexes
選項后,MySQL 會檢查查詢語句是否使用了索引。如果沒有使用索引,并且符合其他慢查詢的條件(如查詢時間超過long_query_time
設定的閾值等),MySQL 會準備記錄這條查詢語句到慢查詢日志中。 - 但是,為了控制記錄的頻率,
log_throttle_queries_not_using_indexes
就發揮作用了。例如,當設置為 5 時,每分鐘最多記錄 5 次未使用索引的查詢。如果在這一分鐘內有大量未使用索引的查詢,超過 5 次后,后續的同類查詢在這一分鐘內就不會再被記錄了。這樣既能保證能夠獲取到未使用索引查詢的關鍵信息,又能夠避免日志文件被過多相似的記錄填滿。
- 當開啟
記錄慢查詢對性能的影響
開啟慢查詢日志會對系統性能產生一定影響,因為記錄日志需要消耗磁盤 I/O 資源。在高并發寫入的場景下,這種影響可能會稍明顯。如果 MySQL 是主從結構,可考慮在從服務器上開啟慢查詢日志,以減少對主服務器性能的影響
實際案例說明
# User@Host: root[root] @ serverName [10.256.22.2] Id: 249625
# Query_time: 0.016972 Lock_time: 0.000005 Rows_sent: 11 Rows_examined: 19185
use test-dev;
SET timestamp=1749630891;
SELECT * FROM *** GROUP BY **;
# Time: 2025-06-11T16:35:44.791481+08:00
# User@Host: [] @ [] Id: 249254
# Query_time: 0.041186 Lock_time: 0.000076 Rows_sent: 0 Rows_examined: 0
use tmp_dev;
SET timestamp=1749630944;
throttle: 17 'index not used' warning(s) suppressed.;
# Time: 2025-06-11T16:36:44.807640+08:00
# User@Host: [] @ [] Id: 249254
# Query_time: 0.015413 Lock_time: 0.000041 Rows_sent: 0 Rows_examined: 0
SET timestamp=1749631004;
throttle: 11 'index not used' warning(s) suppressed.;
# Time: 2025-06-11T16:37:44.821526+08:00
# User@Host: [] @ [] Id: 249565
# Query_time: 0.010364 Lock_time: 0.000032 Rows_sent: 0 Rows_examined: 0
SET timestamp=1749631064;
throttle: 13 'index not used' warning(s) suppressed.;
在 MySQL 慢查詢日志中,每條記錄通常以 # User@Host:
開始,接著記錄了查詢的執行時間、用戶、主機、查詢相關的性能指標,以及查詢語句本身等信息。以下是對上述日志信息的詳細解釋:
第一條記錄
-
# User@Host: root[root] @ serverName [10.256.22.2] Id: 249625
- 表示執行查詢的用戶是
root
,客戶端主機是serverName
,其 IP 地址是10.256.22.2
,連接的線程 ID 是 249625。
- 表示執行查詢的用戶是
-
# Query_time: 0.016972 Lock_time: 0.000005 Rows_sent: 11 Rows_examined: 19185
Query_time
:查詢實際執行的時間是 0.016972 秒。Lock_time
:獲取鎖所花費的時間是 0.000005 秒。Rows_sent
:查詢返回的行數是 11 行。Rows_examined
:查詢過程中掃描的行數是 19185 行,這表明查詢可能沒有使用索引或者索引使用效率低,導致掃描了大量的數據行。
-
use test-dev;
- 表示該查詢是在
test-dev
數據庫中執行的。
- 表示該查詢是在
-
SET timestamp=1749630891;
- 設置了時間戳,對應的時間可以通過 Unix 時間戳轉換工具轉換為具體時間。
-
SELECT ...
- 這是具體的查詢語句。
-
# Time: 2025-06-11T16:35:44.791481+08:00
- 這是查詢執行的時間戳,表明該查詢是在 2025 年 6 月 11 日 16 點 35 分 44 秒左右執行的。
第二條記錄
-
# User@Host: [] @ [] Id: 249254
- 這里的用戶和主機信息顯示為
[]
,可能是因為在日志中未記錄具體的用戶和主機信息,或者該查詢是由系統內部進程或其他未明確標識的客戶端發起的,連接的線程 ID 是 249254。
- 這里的用戶和主機信息顯示為
-
# Query_time: 0.041186 Lock_time: 0.000076 Rows_sent: 0 Rows_examined: 0
Query_time
:查詢實際執行的時間是 0.041186 秒。Lock_time
:獲取鎖所花費的時間是 0.000076 秒。Rows_sent
:查詢返回了 0 行數據。Rows_examined
:查詢過程中沒有掃描到任何行,這可能是因為查詢條件沒有匹配到任何數據,或者表中沒有數據。
-
use tmp_dev;
- 表示該查詢是在
tmp_dev
數據庫中執行的。
- 表示該查詢是在
-
SET timestamp=1749630944;
- 設置了時間戳,對應的時間可以通過 Unix 時間戳轉換工具轉換為具體時間。
-
throttle: 17 'index not used' warning(s) suppressed.;
- 這提示有 17 個 “index not used” 的警告被抑制,表明該查詢沒有使用索引,這可能是導致查詢性能不佳的一個因素。
-
# Time: 2025-06-11T16:36:44.807640+08:00
- 這是查詢執行的時間戳,表明該查詢是在 2025 年 6 月 11 日 16 點 36 分 44 秒左右執行的。
第三條記錄
-
# User@Host: [] @ [] Id: 249254
- 同樣未明確顯示用戶和主機信息,連接的線程 ID 是 249254。
-
# Query_time: 0.015413 Lock_time: 0.000041 Rows_sent: 0 Rows_examined: 0
Query_time
:查詢實際執行的時間是 0.015413 秒。Lock_time
:獲取鎖所花費的時間是 0.000041 秒。Rows_sent
:查詢返回了 0 行數據。Rows_examined
:查詢過程中沒有掃描到任何行。
-
SET timestamp=1749631004;
- 設置了時間戳,對應的時間可以通過 Unix 時間戳轉換工具轉換為具體時間。
-
throttle: 11 'index not used' warning(s) suppressed.;
- 提示有 11 個 “index not used” 的警告被抑制,表明該查詢也沒有使用索引。
-
# Time: 2025-06-11T16:37:44.821526+08:00
- 這是查詢執行的時間戳,表明該查詢是在 2025 年 6 月 11 日 16 點 37 分 44 秒左右執行的。
第四條記錄
-
# User@Host: [] @ [] Id: 249565
- 未明確顯示用戶和主機信息,連接的線程 ID 是 249565。
-
# Query_time: 0.010364 Lock_time: 0.000032 Rows_sent: 0 Rows_examined: 0
Query_time
:查詢實際執行的時間是 0.010364 秒。Lock_time
:獲取鎖所花費的時間是 0.000032 秒。Rows_sent
:查詢返回了 0 行數據。Rows_examined
:查詢過程中沒有掃描到任何行。
-
SET timestamp=1749631064;
- 設置了時間戳,對應的時間可以通過 Unix 時間戳轉換工具轉換為具體時間。
-
throttle: 13 'index not used' warning(s) suppressed.;
- 提示有 13 個 “index not used” 的警告被抑制,表明該查詢也沒有使用索引。
-
# Time: 2025-06-11T16:38:44.83+08:00
- 這是查詢執行的時間戳,表明該查詢是在 2025 年 6 月 11 日 16 點 38 分 44 秒左右執行的。
綜上所述,在這些慢查詢日志記錄中,有的查詢返回了數據并掃描了大量行,有的查詢未返回數據且沒有掃描到行,且很多查詢存在未使用索引的情況,這可能是導致查詢速度慢或效率低的原因之一。