1. 程式人生 > 其它 >面試題 MySQL的慢查詢、如何監控、如何排查?

面試題 MySQL的慢查詢、如何監控、如何排查?

技術標籤:MySqlmysqlsql資料庫

1. 慢查詢和慢查詢日誌

慢查詢,顧名思義就是很慢的查詢。MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指執行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。long_query_time的預設值為10s。預設情況下,Mysql資料庫並不啟動慢查詢日誌,需要我們手動來設定這個引數,當然,如果不是調優需要的話,一般不建議啟動該引數,因為開啟慢查詢日誌或多或少會帶來一定的效能影響。慢查詢日誌支援將日誌記錄寫入檔案,也支援將日誌記錄寫入資料庫表。

要使用慢查詢日誌,首先要檢查慢查詢日誌是否開啟,如果沒有,將其開啟,並設定慢查詢閾值即慢查詢檔案儲存位置等屬性。通過下面的命令檢視相關屬性

show variables like '%query%';

主要看這三個屬性:

  • long_query_time :10.000000:查詢超過10秒被定義為慢語句
  • slow_query_log :OFF:是否開啟慢查詢日誌
  • slow_query_log_file :/usr/local/mysql/data/slow.log:慢查詢日誌檔案所在位置

使用以下命令設定這些屬性值:

set global slow_query_log = ON; # 開啟慢查詢日誌
set global long_query_time = 1; # 超過1秒的語句被定義為慢語句,注意設定了之後需要重新連線才有效

2. 檢視慢查詢的執行情況(監控慢查詢)

2.1 檢視曾經執行完成的慢查

使用日誌分析工具mysqldumpslow來分析慢查詢日誌。

2.2 檢視正在進行的慢查SQL

使用show processlist命令顯示使用者正在執行的執行緒。需要注意的是,除了 root 使用者能看到所有正在執行的執行緒外,其他使用者都只能看到自己正在執行的執行緒。show processlist 顯示的資訊都是來自MySQL系統庫 information_schema 中的 processlist 表。這個表中有這些資訊:

  • Id:就是這個執行緒的唯一標識,當我們發現這個執行緒有問題的時候,可以通過 kill 命令,加上這個Id值將這個執行緒殺掉。是這個表的主鍵。
  • User:就是指啟動這個執行緒的使用者。
  • Host:記錄了傳送請求的客戶端的 IP 和 埠號。通過這些資訊在排查問題的時候,我們可以定位到是哪個客戶端的哪個程序傳送的請求。
  • DB:當前執行的命令是在哪一個資料庫上。如果沒有指定資料庫,則該值為 NULL 。
  • Command:是指此刻該執行緒正在執行的命令。這個很複雜,下面單獨解釋
  • Time:表示該執行緒處於當前狀態的時間,單位是秒。
  • State:執行緒的狀態,和 Command 對應,下面單獨解釋。
  • Info:一般記錄的是執行緒執行的語句。預設只顯示前100個字元,也就是你看到的語句可能是截斷了的,要看全部資訊,需要使用 show full processlist。

我們可以在processlist 中查詢執行時間超所某值的執行緒,如:

select * frominformation_schem.processlist where Command != 'Sleep' and Time > 300 order by Time desc;

2.3 通過在SQL語句前加上explain命令,來顯示這句SQL語句的執行計劃。

3. 如何優化慢查詢

當通過排查定位到慢查詢sql後,就需要通過explain命令分析sql的執行計劃並進行相應的優化

  • 如果是因為沒走索引,就要建合適的索引
  • 因為mysql查詢優化器會誤使用非預期索引導致語句查詢緩慢,這時候需要修改sql邏輯引導優化器使用正確的索引,或者強制(force index)使用我們預期的索引
  • 如果是因為資料表太大,即使走了索引也依然很慢,這時要考慮分表