JAVA中Explain注解用法,mysql之explain详解(分析索引最佳使用)
mysql之explain詳解(分析索引最佳使用)
mysql explain用于分析sql 語句的執行及數據庫索引的使用。本文將致力于幫助大家充分理解explain所返回的各項參數,從而使大家快速掌握explain用法技巧。如果你在看其他教程或視頻后仍覺得云里霧里。那么請通讀本文。
用法
explain的用法相當簡潔,直接在sql語句前加上EXPLAIN 即可
-- 實際SQL,查找租戶為測試的用戶,并排序
select * from uw_tenant where tenant_name like '%test%' order by tenant_name
-- 查看SQL是否使用索引,前面加上explain即可
explain select * from uw_tenant where tenant_name like '%test%' order by tenant_name
使用explain來優化mysql的速度
使用explain之后會有以下元素id、select_type、table、type、possible_key、key、key_len、ref、rows、Extra 下面將一一對上面的元素進行分析。
id
id是標識為一個序號,也可以說是sql的執行順序,序號越大越先執行,如果序號一樣則按順序執行
select_type
SIMPLE: 指示非子查詢和union的簡單查詢。
PRIMARY: 指示在有子查詢的語句中最外面的select,主查詢。
UNION: 指示在使用union語句的第二個或后面的select。
DEPENDENT UNION: 子查詢union語句的第二個或后面的select
UNION RESULT:子查詢union語句的第二個或后面的select
SUBQUERY:子查詢語句
DEPENDENT SUBQUERY:子查詢中第一個語句。
DERIVED:派生表的SELECT(FROM子句的子查詢)。
table
就是表名,本行記錄對應查詢所應用的表。可以通過table表名幫助定位查詢。
使用explain時,有時table字段顯示的并不是表名,而是 derived2 或 derived3 等等。。。 即 derived x 代表的是id為x的查詢所得的結果集。
type
這列很重要,顯示了連接使用了哪種類別,有無使用索引. 從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和ALL ALL < index < range ~ index_merge < ref < eq_ref < const < system
system 這是const聯接的一個特例,表僅有一行滿足條件
const 表最多一個匹配行,他將在查詢開始時被讀取,因為僅有一行,在這行的列值可被優化器剩余部分任務是常數
eq_ref 對于每個來自前面表的行組合,從該表讀取一行,它用在一個索引的所有部分被聯接使用并且索引是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:
index_subquery 該聯接類型類似于unique_subquery??梢蕴鎿QIN子查詢,但只適合下列形式的子查詢中的非唯一索引 .range
只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。key_len包含所使用索引的最長關鍵元素。在該類型中ref列為NULL。當使用=、<>、>、>=、、BETWEEN或者IN操作符,用常量比較關鍵字列時,可以使用range
index 該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小。當查詢只使用作為單索引一部分的列時,MySQL可以使用該聯接類型。
All 對于每個來自于先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,這通常不好,并且通常在它情況下很差。通??梢栽黾痈嗟乃饕灰褂肁LL,使得行能基于前面的表中的常數值或列值被檢索出。
possible_keys
possible_keys列指出MySQL可能使用哪個索引在該表中找到行。注意,該列完全獨立于EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實際上不能按生成的表次序使用。
如果該列是NULL,則沒有相關的索引。在這種情況下,可以通過檢查WHERE子句看是否它引用某些列或適合索引的列來提高你的查詢性能。如果是這樣,創造一個適當的索引并且再次用EXPLAIN檢查查詢
key
key列顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
key_len
key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。 使用的索引的長度。在不損失精確性的情況下,長度越短越好
ref
ref列顯示使用哪個列或常數與key一起從表中選擇行。
rows
rows列顯示MySQL認為它執行查詢時必須檢查的行數。
Extra
該列包含MySQL解決查詢的詳細信息,下面詳細.
Distinct 一旦MYSQL找到了與行相聯合匹配的行,就不再搜索了
Not exists MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行, 就不再搜索了
Range checked for each Record(index map:#) 沒有找到理想的索引,因此對于從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。這是使用索引的最慢的連接之一
Using filesort 看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行 不能通過索引順序達到排序效果. 一般有 Using filesort, 都建議優化去掉, 因為這樣的查詢 CPU 資源消耗大.
Using index 列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對表的全部的請求列都是同一個索引的部分的時候
Using temporary 看到這個的時候,查詢需要優化了。這里,MYSQL需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行ORDERBY上,而不是GROUP BY上
Using where 使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,并且連接類型ALL或index,這就會發生,或者是查詢有問題
索引最佳實踐
聯合索引的全值匹配
最左前綴原則(mysql會自動調整查詢條件順序)
不要在索引列上做計算
索引范圍的后面的列不使用索引
盡量不使用select*
!=,<> 不能使用索引
is null,is not null不走索引
通配符開頭不能走索引
字符串不加‘’,不走索引,明確字符和數字,不能更改類型查詢
少用or
優化實戰
最左前綴不要使用范圍查詢,否則索引失效,
使用覆蓋索引
第一個索引失效,后面的索引都失效
聯合索引第一個字段不要用范圍
order by 字段如果沒有索引,則extra會出現useFilesort
小表先執行,小表驅動大表
總結
在實際工作中可以多嘗試使用explain去優化sql,特別是一些復雜一點的。這篇文章主要還是介紹explain的基本用法,后面應該會專門寫兩篇關于sql優化相關的文章。當然這種優化類的主要適用于開發人員,各位如果發現對你有幫助記得關注一下公眾號:科比可比克。你的關注是我最大的動力。
總結
以上是生活随笔為你收集整理的JAVA中Explain注解用法,mysql之explain详解(分析索引最佳使用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞猪双11:活动商品成交额劲增超80%,
- 下一篇: 中兴通讯展示最新应用实践:包含AI智算中