目錄
一:爲什麼要進行性能分析
在MSYQL中當數據量大的時候,查詢會變得特別慢,特別卡。這時候我們在寫SQL時就需要特別小心,避免由於SQL導致查詢性能瓶頸(說實話,這點真的認爲ORACLE做的比MYSQL好得多)。
二:navcat快速進行性能分析
navcat真是個比較優秀的工具,因爲一開始navcat用習慣了。
1.先來看一下一個100多萬條數據表的查詢:
2.添加limit查詢
本來認爲沒什麼問題的,畢竟100多萬條查詢幾秒很正常。但是突發奇想加上了limit10
3.navcat打開語句分析第一步:執行計劃
有問題了,百度一下,查出來什麼加上limit查詢有了範圍就不進行全表查詢什麼的,總感覺不對勁,然後看到語句分析。
查詢結束後按照如圖所示查看執行計劃:
解釋下各個字段的含義:
id:不用問。
select_type: select查詢的類型,主要是區別普通查詢和聯合查詢、子查詢之類的複雜查詢。
a.SIMPLE:查詢中不包含子查詢或者UNION
b.查詢中若包含任何複雜的子部分,最外層查詢則被標記爲:PRIMARY
c.在SELECT或WHERE列表中包含了子查詢,該子查詢被標記爲:SUBQUERY
d.在FROM列表中包含的子查詢被標記爲:DERIVED(衍生)
e.若第二個SELECT出現在UNION之後,則被標記爲UNION;若UNION包含在 FROM子句的子查詢中,外層 SELECT將被標記爲:DERIVED
f.從UNION表獲取結果的SELECT被標記爲:UNION RESULT
table:查詢所對應的表
partitions: 分區,一般用不到
type:表示MySQL在表中找到所需行的方式,又稱“訪問類型”,常見類型如下:結果值從好到壞依次是:system > const > eq_ref
> ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來說,得保證查詢至少達到range級別,最好能達到ref。
possible_keys:指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被
查詢使用。
key: 顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示爲NULL。TIPS:查詢中若使用了覆蓋索引,則該索引僅出
現在key列表中。
key_len:表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度,key_len顯示的值爲索引字段的最大可能長度,
並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。
ref:表示上述表的連接匹配條件,即哪些列或常量被用於查找索引列上的值
Extra:包含不適合在其他列中顯示但十分重要的額外信息
由上面可以得到:一些sql優化建議: 儘量避免全表查詢,建立合適的索引,索引字段不要太長(比如varchar(66000))
通過對比發現,執行計劃是一樣沒有什麼不同。
4、navcat打開語句分析第二步:執行狀態。
在上面下面選擇概況:
發現主要區別在Send_data時間消耗有區別。那麼我們來看一下這個名詞是什麼東西?
原來這個狀態的名稱很具有誤導性,所謂的“Sending data”並不是單純的發送數據,而是包括“收集 + 發送 數據”。這裏的關鍵是爲什麼要收集數據,原因在於:mysql使用“索引”完成查詢結束後,mysql得到了一堆的行id,如果有的列並不在索引中,mysql需要重新到“數據行”上將需要返回的數據讀取出來返回個客戶端。
5、navcat打開語句分析第三步:時間分佈。
首先打開配置:set profiling=on;
執行完查詢後,使用show profiles查看query id;
使用show profile for query query_id查看詳細信息;
好吧問題果然出在這個上面。
6.排查問題
發現我去 全是text大文本字段,有些腦殼疼。
show table status,查看溢出信息,溢出數據會被隨機讀取,造成讀取耗時多。
7.解決問題
(1)百度優化text,blob等等大字段的優化
(2)業務拆分,很顯然 text的字段可以單獨拆分出一個表字段。
三:語句分析初步得出優化建議
1.儘量合理使用索引
2.儘量避免表設計字段過長
3.儘量添加limit條件