如何分析慢查詢
首先需要明確查詢效能低下的基礎原因:訪問資料過多。
還有一種可能性:篩選大量資料,但是並不常見。
通常情況下效能低下的查詢都可以通過減少訪問資料量的方式進行優化。
分析慢查詢
兩種分析方法:
- 應用程式是否在檢索大量超過需要的資料。
- 確認MySQL伺服器是否在分析大量超過需要的資料行。
一、是否向資料庫請求了不需要的資料
描述:一個查詢請求了超過實際需要的資料,但是多餘的部分並沒有什麼用處而被丟掉。
影響:這會給MySql伺服器帶來額外的負擔,增加網路開銷,消耗應用伺服器的CPU和記憶體資源
典型案例:
-
查詢不需要的記錄:如分頁查詢中每次都全部查詢,但是隻顯示一部分。
-
多表關聯時返回全部列:
比如典型的”圖書分類-圖書“模式,該模式包含三個資料表:圖書、圖書分類、圖書-圖書分類
我們想查詢A分類中所有的圖書
一種錯誤的寫法是:
SELECT * FROM 圖書 INNER JOIN 圖書-圖書分類 ON xxxx INNER JOIN 圖書分類 ON xxxx WHERE 圖書分類.name="A"
上面的寫法返回了整個關聯表的內容
我們應該只獲取所需,正確的寫法如下
SELECT 圖書.* FROM ....
-
總是取出全部列:每次使用SELECT *的時候都應該小心,取出所有的列、會導致優化器無法完成索引覆蓋掃描這類優化,同時帶來額外的I/O、記憶體和CPU的消耗。在阿里巴巴的規範中,就明確禁止了使用*進行查詢
-
重複查詢相同的資料:對於不會修改的較為持久的資訊,如使用者頭像,反覆查詢將浪費資源,快取為更好的選擇。
二、是否在掃描額外的記錄
確定了查詢只返回了需要的資料後,接下來優化是否掃描過多的資料。
這裡有衡量查詢開銷的三個最簡單的指標
- 響應時間
- 掃描的行數
- 返回的行數
沒有哪個指標可以完美衡量查詢的開銷,但是大致反映了MySQL在內部執行查詢時需要訪問多少資料,並可以大概推算出查詢執行的時間。這三個指標會記錄著MySQL的慢日誌中
檢查慢日誌是找出掃描行數過多的查詢的好辦法
參考這片文章https://juejin.cn/post/6844903473079648264
首先我們給出幾個理想的狀態
理想的查詢:
- 響應時間快
- 掃描的行數與返回的行數相同
- 使用盡可能快的訪問型別
使用EXPLAIN可以分析查詢執行的方式,舉例如下
EXPLAIN SELECT * FROM xxx;
訪問型別有很多種分別有
全表掃描、索引掃描、範圍掃描、唯一索引查詢、常數引用等。
一般情況下,MySQL使用如下三種方式應用WHERE,從好到壞依次為:
-
在索引中使用WHERE條件過濾(在儲存引擎層完成,即WHERE為索引)
-
使用索引覆蓋掃描來返回記錄,直接從索引中過濾不需要的記錄並返回命中結果。(MySQL伺服器層完成,Extra列為Using Index)
-
從資料表中返回資料,然後過濾不滿足條件的記錄(Extra列中出現Using Where)。
若存在掃描大量資料但只返回少數的行
- 使用索引覆蓋掃描,把需要的列放置在索引中,這樣儲存引擎無須回表獲取對應行(聚簇索引)。
- 改變庫表結構。例如使用單獨的彙總表
- 重寫這個複雜的查詢,讓MySQL優化器能以更優化的方式執行這個查詢。