一. EXPLAIN執行計劃分析 EXPLAIN可以幫助開發人員分析SQL問題,EXPLAIN顯示了MySQL如何使用使用SQL執行計劃,可以幫助開發人員寫出更優化的查詢語句。使用方法,在select語句前加上EXPLAIN就可以了。 ...
前言
從今天開始本系列文章就帶各位小伙伴學習資料庫技術。資料庫技術是Java開發中必不可少的一部分知識內容。也是非常重要的技術。本系列教程由淺入深, 全面講解資料庫體系。 非常適合零基礎的小伙伴來學習。
全文大約 【1965】字,不說廢話,只講可以讓你學到技術、明白原理的純乾貨!本文帶有豐富案例及配圖視頻,讓你更好的理解和運用文中的技術概念,並可以給你帶來具有足夠啟迪的思考...
一. EXPLAIN執行計劃分析
EXPLAIN可以幫助開發人員分析SQL問題,EXPLAIN顯示了MySQL如何使用使用SQL執行計劃,可以幫助開發人員寫出更優化的查詢語句。使用方法,在select語句前加上EXPLAIN就可以了。
1. 舉個例子:
下麵是一個最普通的查詢語句,用EXPLAIN進行分析演示。
EXPLAIN SELECT * FROM student;
結果:
2. 結果的列的說明如下:
id : SELECT識別符。這是SELECT查詢序列號。這個不重要。
select_type: 表示SELECT語句的類型。
- simple:簡單select(不使用union或子查詢)。
- primary:最外面的select。
- union:union中的第二個或後面的select語句。
- dependent union:union中的第二個或後面的select語句,取決於外面的查詢。
- union result:union的結果。
- subquery:子查詢中的第一個select。
- dependent subquery:子查詢中的第一個select,取決於外面的查詢。
- derived:導出表的select(from子句的子查詢)。
table: 顯示這查詢的數據是關於哪張表的。
type: 區間索引,這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為。
system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來說,得保證查詢至少達到range級別,最好能達到ref。
- system:表僅有一行,這是const類型的特列,平時不會出現,這個也可以忽略不計。
- const:數據表最多只有一個匹配行,因為只匹配一行數據,所以很快。
- eq_ref:mysql手冊是這樣說的:"對於每個來自於前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型。它用在一個索引的所有部分被聯接使用並且索引是UNIQUE或PRIMARY KEY"。eq_ref可以用於使用=比較帶索引的列。
- ref:查詢條件索引既不是UNIQUE也不是PRIMARY KEY的情況。ref可用於=或<或>操作符的帶索引的列。
- ref_or_null:該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經常使用該聯接類型的優化。
- index_merge:該聯接類型表示使用了索引合併優化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關鍵元素。
- unique_subquery:該類型替換了下麵形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一個索引查找函數,可以完全替換子查詢,效率更高。
- index_subquery:該聯接類型類似於unique_subquery。可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
- range:只檢索給定範圍的行,使用一個索引來選擇行。
- index:該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小。
- ALL:對於每個來自於先前的表的行組合,進行完整的表掃描(性能最差)。
possible_keys: 指出MySQL能使用哪個索引在該表中找到行。如果是空的,沒有相關的索引。這時要提高性能,可通過檢驗WHERE子句,看是否引用某些欄位,或者檢查欄位不是適合索引。
key: 實際使用到的索引。如果為NULL,則沒有使用索引。如果為primary的話,表示使用了主鍵。
key_len: 最長的索引寬度。如果鍵是NULL,長度就是NULL。在不損失精確性的情況下,長度越短越好。
ref: 顯示使用哪個列或常數與key一起從表中選擇行。
rows: 顯示MySQL認為它執行查詢時必須檢查的行數。
Extra: 執行狀態說明,該列包含MySQL解決查詢的詳細信息。
- Distinct:MySQL發現第1個匹配行後,停止為當前的行組合搜索更多的行。
- Not exists:MySQL能夠對查詢進行LEFT JOIN優化,發現1個匹配LEFT JOIN標準的行後,不再為前面的的行組合在該表內檢查更多的行。
- range checked for each record (index map: #):MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。
- Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。
- Using index:從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息。
- Using temporary:為瞭解決查詢,MySQL需要創建一個臨時表來容納結果。
- Using where:WHERE 子句用於限制哪一個行匹配下一個表或發送到客戶。
- Using sort_union(...), Using union(...), Using intersect(...):這些函數說明如何為index_merge聯接類型合併索引掃描。
- Using index for group-by:類似於訪問表的Using index方式,Using index for group-by表示MySQL發現了一個索引,可以用來查 詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬碟訪問實際的表。
二. 結語
最後在這裡對本文核心要點進行總結:
- 本節講瞭如何使用EXPLAIN執行計划進行SQL語句分析,判斷SQL語句哪裡慢。
- 比較重要的分析欄位有select_type、type、possible_keys、key、ref、rows,這幾列需要熟練掌握。