日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

explain mysql怎么用_[mysql] mysql explain 使用

發(fā)布時間:2025/3/15 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 explain mysql怎么用_[mysql] mysql explain 使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優(yōu)化的查詢語句。

先解析一條sql語句,看出現(xiàn)什么內(nèi)容

EXPLAINSELECTs.uid,s.username,s.name,f.email,f.mobile,f.phone,f.postalcode,f.address

FROMuchome_spaceASs,uchome_spacefieldASf

WHERE1ANDs.groupid=0

ANDs.uid=f.uid

1. id

SELECT識別符。這是SELECT查詢序列號。這個不重要,查詢序號即為sql語句執(zhí)行的順序,看下面這條sql

EXPLAINSELECT*FROM(SELECT*FROMuchome_spaceLIMIT10)ASs

它的執(zhí)行結(jié)果為

可以看到這時的id變化了

2.select_type

select類型,它有以下幾種值

2.1 simple 它表示簡單的select,沒有union和子查詢

2.2 primary 最外面的select,在有子查詢的語句中,最外面的select查詢就是primary,上圖中就是這樣

2.3 union union語句的第二個或者說是后面那一個.現(xiàn)執(zhí)行一條語句,explainselect * from uchome_space limit 10 union select * from uchome_space limit 10,10

會有如下結(jié)果

第二條語句使用了union

2.4 dependent union??? UNION中的第二個或后面的SELECT語句,取決于外面的查詢

2.5 union result??????? UNION的結(jié)果,如上面所示

還有幾個參數(shù),這里就不說了,不重要

3 table

輸出的行所用的表,這個參數(shù)顯而易見,容易理解

4 type

連接類型。有多個參數(shù),先從最佳類型到最差類型介紹重要且困難

4.1 system

表僅有一行,這是const類型的特列,平時不會出現(xiàn),這個也可以忽略不計

4.2 const

表最多有一個匹配行,const用于比較primary key 或者unique索引。因為只匹配一行數(shù)據(jù),所以很快

記住一定是用到primary key 或者unique,并且只檢索出兩條數(shù)據(jù)的 情況下才會是const,看下面這條語句

explain SELECT * FROM `asj_admin_log` limit 1,結(jié)果是

雖然只搜索一條數(shù)據(jù),但是因為沒有用到指定的索引,所以不會使用const.繼續(xù)看下面這個

explain SELECT * FROM `asj_admin_log` where log_id = 111

log_id是主鍵,所以使用了const。所以說可以理解為const是最優(yōu)化的

4.3eq_ref

對于eq_ref的解釋,mysql手冊是這樣說的:"對于每個來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯(lián)接類型,除了const類型。它用在一個索引的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY"。eq_ref可以用于使用=比較帶索引的列。看下面的語句

explain select * from uchome_spacefield,uchome_space where uchome_spacefield.uid = uchome_space.uid

得到的結(jié)果是下圖所示。很明顯,mysql使用eq_ref聯(lián)接來處理uchome_space表。

目前的疑問:

4.3.1 為什么是只有uchome_space一個表用到了eq_ref,并且sql語句如果變成

explain select * from uchome_space,uchome_spacefield where uchome_space.uid = uchome_spacefield.uid

結(jié)果還是一樣,需要說明的是uid在這兩個表中都是primary

4.4 ref 對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯(lián)接只使用鍵的最左邊的前綴,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關(guān)鍵字選擇單個行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯(lián)接類型是不錯的。

看下面這條語句explain select * from uchome_space where uchome_space.friendnum = 0,得到結(jié)果如下,這條語句能搜出1w條數(shù)據(jù)

4.5ref_or_null該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經(jīng)常使用該聯(lián)接類型的優(yōu)化。

上面這五種情況都是很理想的索引使用情況

4.6 index_merge 該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關(guān)鍵元素。

4.7unique_subquery

4.8index_subquery

4.9 range 給定范圍內(nèi)的檢索,使用一個索引來檢查行。看下面兩條語句

explain select * from uchome_space where uid in (1,2)

explain select * from uchome_space where groupid in (1,2)

uid有索引,groupid沒有索引,結(jié)果是第一條語句的聯(lián)接類型是range,第二個是ALL.以為是一定范圍所以說像 between也可以這種聯(lián)接,很明顯

explain select * from uchome_space where friendnum = 17

這樣的語句是不會使用range的,它會使用更好的聯(lián)接類型就是上面介紹的ref

4.10 index???? 該聯(lián)接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數(shù)據(jù)文件小。(也就是說雖然all和Index都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀的)

當查詢只使用作為單索引一部分的列時,MySQL可以使用該聯(lián)接類型。

4.11? ALL? 對于每個來自于先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,這通常不好,并且通常在它情況下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常數(shù)值或列值被檢索出。

5 possible_keys提示使用哪個索引會在該表中找到行,不太重要

6 keysMYSQL使用的索引,簡單且重要

7 key_lenMYSQL使用的索引長度

8 refref列顯示使用哪個列或常數(shù)與key一起從表中選擇行。

9 rows顯示MYSQL執(zhí)行查詢的行數(shù),簡單且重要,數(shù)值越大越不好,說明沒有用好索引

10 Extra? 該列包含MySQL解決查詢的詳細信息。

10.1Distinct????MySQL發(fā)現(xiàn)第1個匹配行后,停止為當前的行組合搜索更多的行。一直沒見過這個值

10.2Not exists

10.3range checked for each record

沒有找到合適的索引

10.4 using filesort

MYSQL手冊是這么解釋的“MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。通過根據(jù)聯(lián)接類型瀏覽所有行并為所有匹配WHERE子句的行保存排序關(guān)鍵字和行的指針來完成排序。然后關(guān)鍵字被排序,并按排序順序檢索行。”目前不太明白

10.5 using index 只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的信息。這個比較容易理解,就是說明是否使用了索引

explain select * from ucspace_uchome where uid = 1的extra為using index(uid建有索引)

explain select count(*) from uchome_space where groupid=1 的extra為using where(groupid未建立索引)

10.6 using temporary

為了解決查詢,MySQL需要創(chuàng)建一個臨時表來容納結(jié)果。典型情況如查詢包含可以按不同情況列出列的GROUP BY和ORDER BY子句時。

出現(xiàn)using temporary就說明語句需要優(yōu)化了,舉個例子來說

EXPLAIN SELECT ads.id FROMads, city WHERE?? city.city_id = 8005?? AND ads.status = 'online'?? AND city.ads_id=ads.idORDER BY?ads.id?desc

id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????? rows? filtered? Extra

------? -----------? ------? ------? --------------? -------? -------? --------------------? ------? --------? -------------------------------

1? SIMPLE??????cityref???? ads_id,city_id? city_id? 4??????? const?????????????????? 2838??? 100.00?Using temporary; Using filesort

1? SIMPLE?????? ads???? eq_ref? PRIMARY???????? PRIMARY? 4??????? city.ads_id?????? 1??? 100.00? Using where

這條語句會使用using temporary,而下面這條語句則不會

EXPLAIN SELECT ads.id FROMads, city WHERE?? city.city_id = 8005?? AND ads.status = 'online'?? AND city.ads_id=ads.idORDER BYcity.ads_id?desc

id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????? rows? filtered? Extra

------? -----------? ------? ------? --------------? -------? -------? --------------------? ------? --------? ---------------------------

1? SIMPLE??????cityref???? ads_id,city_id? city_id? 4??????? const?????????????????? 2838??? 100.00?Using where; Using filesort

1? SIMPLE?????? ads??? eq_ref? PRIMARY???????? PRIMARY? 4??????? city.ads_id?????? 1??? 100.00? Using where

這是為什么呢?他倆之間只是一個order by不同,MySQL 表關(guān)聯(lián)的算法是 Nest Loop Join,是通過驅(qū)動表的結(jié)果集作為循環(huán)基礎(chǔ)數(shù)據(jù),然后一條一條地通過該結(jié)果集中的數(shù)據(jù)作為過濾條件到下一個表中查詢數(shù)據(jù),然后合并結(jié)果。EXPLAIN 結(jié)果中,第一行出現(xiàn)的表就是驅(qū)動表(Important!)以上兩個查詢語句,驅(qū)動表都是 city,如上面的執(zhí)行計劃所示!

對驅(qū)動表可以直接排序,對非驅(qū)動表(的字段排序)需要對循環(huán)查詢的合并結(jié)果(臨時表)進行排序(Important!)

因此,order by ads.id desc 時,就要先 using temporary 了!

驅(qū)動表的定義

wwh999?在 2006年總結(jié)說,當進行多表連接查詢時,?[驅(qū)動表]?的定義為:

1)指定了聯(lián)接條件時,滿足查詢條件的記錄行數(shù)少的表為[驅(qū)動表];

2)未指定聯(lián)接條件時,行數(shù)少的表為[驅(qū)動表](Important!)。

永遠用小結(jié)果集驅(qū)動大結(jié)果集

今天學到了一個很重要的一點:當不確定是用哪種類型的join時,讓mysql優(yōu)化器自動去判斷,我們只需寫select * from t1,t2 where t1.field = t2.field

10.7 using where

WHERE子句用于限制哪一個行匹配下一個表或發(fā)送到客戶。除非你專門從表中索取或檢查所有行,如果Extra值不為Using where并且表聯(lián)接類型為ALL或index,查詢可能會有一些錯誤。(這個說明不是很理解,因為很多很多語句都會有where條件,而type為all或index只能說明檢索的數(shù)據(jù)多,并不能說明錯誤,useing where不是很重要,但是很常見)

如果想要使查詢盡可能快,應(yīng)找出Using filesort和Using temporary的Extra值。

10.8Using sort_union(...),Using union(...),Using intersect(...)

這些函數(shù)說明如何為index_merge聯(lián)接類型合并索引掃描

10.9Using index for group-by

類似于訪問表的Using index方式,Using index for group-by表示MySQL發(fā)現(xiàn)了一個索引,可以用來查詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤訪問實際的表。并且,按最有效的方式使用索引,以便對于每個組,只讀取少量索引條目。

實例講解

通過相乘EXPLAIN輸出的rows列的所有值,你能得到一個關(guān)于一個聯(lián)接如何的提示。這應(yīng)該粗略地告訴你MySQL必須檢查多少行以執(zhí)行查詢。當你使用max_join_size變量限制查詢時,也用這個乘積來確定執(zhí)行哪個多表SELECT語句。

總結(jié)

以上是生活随笔為你收集整理的explain mysql怎么用_[mysql] mysql explain 使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。