從零開始java數據庫SQL優化(番外):SQL執行性能分析

目錄

 

一:爲什麼要進行性能分析

二:navcat快速進行性能分析

1.先來看一下一個100多萬條數據表的查詢:

2.添加limit查詢

3.navcat打開語句分析第一步:執行計劃

4、navcat打開語句分析第二步:執行狀態。

5、navcat打開語句分析第三步:時間分佈。

6.排查問題

7.解決問題 

三:語句分析初步得出優化建議


一:爲什麼要進行性能分析

  在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條件

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章