日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 程序員小灰
[導(dǎo)讀]Explain被稱為執(zhí)行計劃,在語句之前增加explain關(guān)鍵字,MySQL會在查詢上設(shè)置一個標(biāo)記,模擬MySQL優(yōu)化器來執(zhí)行SQL語句,執(zhí)行查詢時,會返回執(zhí)行計劃的信息,并不執(zhí)行這條SQL。

本文作者王良辰,京東中臺架構(gòu)師,擅長分布式系統(tǒng)及高可用、高并發(fā)系統(tǒng)架構(gòu)與設(shè)計。曾經(jīng)為企業(yè)開發(fā)過多個通用腳手架,推崇以技術(shù)手段提升開發(fā)效率、約束開發(fā)行為。


什么是Explain


Explain被稱為執(zhí)行計劃,在語句之前增加 explain 關(guān)鍵字,MySQL 會在查詢上設(shè)置一個標(biāo)記,模擬MySQL優(yōu)化器來執(zhí)行SQL語句,執(zhí)行查詢時,會返回執(zhí)行計劃的信息,并不執(zhí)行這條SQL。(注意,如果 from 中包含子查詢,仍會執(zhí)行該子查詢,將結(jié)果放入臨時表中)。


Explain可以用來分析SQL語句和表結(jié)構(gòu)的性能瓶頸。通過explain的結(jié)果,可以了解到如數(shù)據(jù)表的查詢順序、數(shù)據(jù)查詢操作的操作類型、哪些索引可以被命中、哪些索引實際會命中、每個數(shù)據(jù)表有多少行記錄被查詢等信息。



Explain命令擴(kuò)展


explain extended


在explain的基礎(chǔ)上提供一些額外的查詢信息,在explian extended執(zhí)行以后,通過show warnings命令可以得到優(yōu)化后的查詢語句,可以看出優(yōu)化器做了哪些工作,還可以通過某些數(shù)據(jù)估算表連接的行數(shù)。


explain partitions


用于分析使用了分區(qū)的表,會顯示出可能用到的分區(qū)。



兩點重要提示


1. Explain結(jié)果是基于數(shù)據(jù)表中現(xiàn)有數(shù)據(jù)的。


2. Explain結(jié)果與MySQL版本有很大的關(guān)系,不同版本的優(yōu)化器的優(yōu)化策略不同。

?


本文示例使用的數(shù)據(jù)庫表




Explain命令(關(guān)鍵字)


explain簡單示例

mysql>explain select * from t_user;


在查詢中的每個”表”會輸出一行,這里的“表”的意義非常廣泛,不僅僅是數(shù)據(jù)庫表,還可以是子查詢、一個union 結(jié)果等。


explain結(jié)果列說明


【id列】


id列是一個有順序的編號,是查詢的順序號,有幾個 select 就顯示幾行。id的順序是按 select 出現(xiàn)的順序增長的。id列的值越大執(zhí)行優(yōu)先級越高越先執(zhí)行,id列的值相同則從上往下執(zhí)行,id列的值為NULL最后執(zhí)行。


【select_type列】


select_type列的值標(biāo)明查詢的類型:


1)simple:表明當(dāng)前行對應(yīng)的select是簡單查詢,不包含子查詢和union


2)primary:表明當(dāng)前行對應(yīng)的select是復(fù)雜查詢中最外層的 select


3)subquery:表明當(dāng)前行對應(yīng)的select是包含在 select 中的子查詢(不在 from 子句中)


4)derived:表明當(dāng)前行對應(yīng)的select是包含在 from 子句中的子查詢。


MySQL會創(chuàng)建一個臨時表來存放子查詢的查詢結(jié)果。用如下的語句示例說明:


explain select (select 1 fromt_user where user_id=1) from (select * from t_group where group_id=1) tmp;



*注意,在資料收集過程中,發(fā)現(xiàn)不同版本的MySQL表現(xiàn)不一致,經(jīng)反復(fù)對比,5.7及以后版本的輸出如下:



很顯然,MySQL在這方面進(jìn)行了優(yōu)化.


*注意,MySQL不同版本Explain表現(xiàn)差異很大,有些場景,從語句層面看,是要使用到索引,但經(jīng)過優(yōu)化器分析,結(jié)合表中現(xiàn)有數(shù)據(jù),如果MySQL認(rèn)為全表掃描性能更優(yōu),則會使用全表掃描。


5)union:表明當(dāng)前行對應(yīng)的select是在 union 中的第二個和隨后的 select


6)union result:表明當(dāng)前行對應(yīng)的select是從 union 臨時表檢索結(jié)果的 select


explain select 1 union all select 2 fromdual;



?????? MySQL5.7及以后同樣做了優(yōu)化



【table列】


table列的結(jié)果表明當(dāng)前行對應(yīng)的select正在訪問哪個表。當(dāng)查詢的子句中有子查詢時,table列是??格式,表示當(dāng)前的select依賴 id=N結(jié)果行對應(yīng)的查詢,要先執(zhí)行 id序號=N 的查詢。當(dāng)存在 union 時,UNION RESULT 的 table 列的值為,N1和N2表示參與 union 的select 行的id序號。


【type列】


type列的結(jié)果表明當(dāng)前行對應(yīng)的select的關(guān)聯(lián)類型或訪問類型,也就是優(yōu)化器決定怎么查找數(shù)據(jù)表中的行,以及查找數(shù)據(jù)行記錄的大概范圍。該列的取值優(yōu)化程度的優(yōu)劣,從最優(yōu)到最差依次為:null>system> const > eq_ref > ref > range > index > ALL。一般來說,要保證查詢達(dá)到range級別,最好達(dá)到ref。


1)null,MySQL優(yōu)化器在優(yōu)化階段分解查詢語句,在優(yōu)化過程中就已經(jīng)可以得到結(jié)果,那么在執(zhí)行階段就不用再訪問表或索引。

explain select min(user_id) from t_user;



這時的函數(shù)min,在索引列user_id中選取最小值,可以直接查找索引來完成,不需要執(zhí)行時再訪問數(shù)據(jù)表。


2)const和system:const出現(xiàn)在用 primary key(主鍵) 或 unique key(唯一鍵) 的所有列與常數(shù)比較時,優(yōu)化器對查詢進(jìn)行優(yōu)化并將其部分查詢轉(zhuǎn)化成一個常量。最多有一個匹配行,讀取1次,速度非???。而system是const的特例,表中數(shù)據(jù)只有一條匹配時為system。此時可以用explain extended+show warnings查看執(zhí)行結(jié)果。


explain extended select * from (select * from t_user where user_id = 1) tmp;


show warnings;




MySQL5.7及以后版本優(yōu)化后:




3)eq_ref:primary key(主鍵)或 unique key(唯一鍵) 索引的所有構(gòu)成部分被join使用 ,只會返回一條符合條件的數(shù)據(jù)行。這是僅次于const的連接類型。


explain select * from t_group_user gu left join t_group g ong.group_id = gu.group_id;



4) ref:與eq_ref相比,ref類型不是使用primary key(主鍵) 或 unique key(唯一鍵)等唯一索引,而是使用普通索引或者聯(lián)合唯一性索引的部分前綴,索引和某個值相比較,可能會找到符合條件的多個數(shù)據(jù)行。


1. 如下示例,使用的group_name是普通索引


explain select * from t_group where group_name= 'group1';



2.關(guān)聯(lián)表查詢


explain select g.group_id from t_group gleft join t_group_user gu on gu.group_id = g.group_id;



5)range:出現(xiàn)在 in(),between ,> ,<, >= 等操作符中。使用一個索引來查詢給定范圍的行。


6)index:掃描全表索引(index是從索引中讀取的,所有字段都有索引,而all是從硬盤中讀?。華LL要快。


explain select * from t_group;



7)all:即全表掃描,需要從頭到尾去查找所需要的行。一般這種情況下這需要增加索引來進(jìn)行查詢優(yōu)化了


explain select * from t_user;



【possible_keys列】


這一列的結(jié)果表明查詢可能使用到哪些索引。但有些時候也會出現(xiàn)出現(xiàn)possible_keys 列有結(jié)果,而 后面的key列顯示 null 的情況,這是因為此時表中數(shù)據(jù)不多,優(yōu)化器認(rèn)為查詢索引對查詢幫助不大,所以沒有走索引查詢而是進(jìn)行了全表掃描。?


如果possible_keys列的結(jié)果是null,則表明沒有相關(guān)的索引。這時,可以通過優(yōu)化where子句,增加恰當(dāng)?shù)乃饕齺硖嵘樵冃阅堋?/span>


【key列】


這一列表明優(yōu)化器實際采用哪個索引來優(yōu)化對該表的訪問。如果沒有使用索引,則該列是 null。


【key_len列】


這一列表明了在索引里使用的字節(jié)數(shù),通過這個值可以大致估算出具體使用了聯(lián)合索引中的前幾個列。?

key_len計算規(guī)則這里不再贅述,不同的數(shù)據(jù)類型所占的字節(jié)數(shù)是不一致的。


【ref列】

這一列表明了在key列記錄的索引中,表查找值所用到的列或常量,常見的有:const(常量),字段名,如user.user_id


【rows列】


這一列表明優(yōu)化器大概要讀取并檢測的行數(shù)。跟實際的數(shù)據(jù)行數(shù)大部分情況是不一致的。


【Extra列】


顧名思義,這一列表明的是額外信息,這一列的取值對優(yōu)化SQL非常有參考意義。常見的重要取值如下:?


1)using index:所有被查詢的字段都是索引列(稱為覆蓋索引),并且where條件是索引的前導(dǎo)列,出現(xiàn)這樣的結(jié)果,是性能高的表現(xiàn)。

explainselect group_id,group_name from t_group;



2)using where:被查詢的列未被索引覆蓋,where條件也并非索引的前導(dǎo)列,表示 MySQL 執(zhí)行器從存儲引擎接收到查詢數(shù)據(jù),再進(jìn)行“后過濾”(Post-filter)。所謂“后過濾”,就是先讀取整行數(shù)據(jù),再檢查此行是否符合 where 句的條件,符合就留下,不符合便丟棄。

explain select * from t_user whereuser_name='user1';



3)using where Using index:被查詢的列被索引覆蓋,并且where條件是索引列之一但是不是索引的前導(dǎo)列,也就是沒有辦法直接通過索引來查詢到符合條件的數(shù)據(jù)

explain select * from t_group where group_name = 'group1';



4)null:被查詢的列沒有被索引覆蓋,但where條件是索引的前導(dǎo)列,此時用到了索引,但是部分列未被索引覆蓋,必須通過“回表查詢”來實現(xiàn),不是純粹地用到了索引,也不是完全沒用到索引

explain select * from t_user where user_id='1';



5)using index condition:與using where類似,查詢的列不完全被索引覆蓋,where條件中是一個前導(dǎo)列的范圍;這種情況未能通過示例顯現(xiàn),可能跟MySQL版本有關(guān)系。


6) using temporary:這表明需要通過創(chuàng)建臨時表來處理查詢。出現(xiàn)這種情況一般是要進(jìn)行優(yōu)化的,用索引來優(yōu)化。創(chuàng)建臨時表的情況:distinct,group by,orderby,子查詢等


explain select distinct user_name from t_user;



explain select distinct group_name fromt_group; --group_name是索引列



7) usingfilesort:在使用order by的情況下出現(xiàn),mysql會對結(jié)果使用一個外部索引排序,而不是按索引次序從表里讀取行。此時mysql會根據(jù)聯(lián)接類型瀏覽所有符合條件的記錄,并保存排序關(guān)鍵字和行指針,然后排序關(guān)鍵字并按順序檢索行信息。這種情況下要考慮使用索引來優(yōu)化的。


explain select * from t_user orderby user_name;



explain select * from t_group order bygroup_name;? --group_name是索引列




查詢優(yōu)化建議


結(jié)合前面的描述,首先看 type列的結(jié)果,如果有類型是 all 時,表示預(yù)計會進(jìn)行全表掃描(fulltable scan)。通常全表掃描的代價是比較大的,建議創(chuàng)建適當(dāng)?shù)乃饕ㄟ^索引檢索避免全表掃描。


再來看下 Extra 列的結(jié)果,如果有出現(xiàn) Using temporary 或者 Using filesort 則要多加關(guān)注:

Using temporary ,表示需要創(chuàng)建臨時表以滿足需求,通常是因為GROUP BY的列沒有索引,或者GROUP BY和ORDER BY的列不一樣,也需要創(chuàng)建臨時表,建議添加適當(dāng)?shù)乃饕?/span>

Using filesort ,表示無法利用索引完成排序,也有可能是因為多表連接時,排序字段不是驅(qū)動表中的字段,因此也沒辦法利用索引完成排序,建議添加適當(dāng)?shù)乃饕?/span>

Using where ,通常是因為全表掃描或全索引掃描時(type 列顯示為 ALL 或index),又加上了WHERE條件,建議添加適當(dāng)?shù)乃饕?/span>



索引使用情況分析


數(shù)據(jù)庫表


主鍵索引:demo_id

聯(lián)合索引:c1,c2,c3



實例說明


實例一:

explain select * from t_demo where c1='d1'and c2='d2' and c3='d3';

explain select * from t_demo where c2='d2'and c1='d1' and c3='d3';

explain select * from t_demo where c3='d3'and c1='d1' and c2='d3';



幾個Sql表現(xiàn)一致

type=ref,ref=const,const,const

執(zhí)行常量等值查詢時,改變索引列的順序并不會更改explain的執(zhí)行結(jié)果,優(yōu)化器會進(jìn)行優(yōu)化,推薦按照索引順序列編寫sql語句。


實列二:

explain select * from t_demo where c1='d1'and c2>'d2' and c3='d3';



explain select * from t_demo where c1='d1'and c3>'d3' and c2='d2';



第一個例子范圍右側(cè)索引失效,使用到了兩個索引。

第二個例子,由于優(yōu)化器優(yōu)化的原因,使用到了全部的三個索引。


實例三:

explain select * from t_demo wherec1>'c' and c2='d2' and c3='d3';



explain select * from t_demo wherec1>'e' and c2='d2' and c3='d3';



從上面兩個實例可以發(fā)現(xiàn),同樣使用最左的索引列范圍查詢,有些情況未用到索引,做了全表掃描(第一個例子);有些情況使用到了索引(第二個例子)。


經(jīng)反復(fù)驗證,發(fā)現(xiàn)如下規(guī)律(不一定可靠),也可能與數(shù)據(jù)的第一行或最小值相關(guān)。

1. 跟存儲的數(shù)據(jù)有關(guān)

2. 在大于條件下,如果條件數(shù)據(jù)小于列數(shù)據(jù),則索引無效;如果條件數(shù)據(jù)大于列數(shù)據(jù),則索引有效;


在設(shè)計查詢條件時,請注意規(guī)避。

針對第一個例子,可以采用覆蓋索引的方式優(yōu)化。


實例四:

explain select * from t_demo where c1='d1'and c2='d2' order by c3;


explain select * from t_demo where c1='d1'order by c3;


explain select * from t_demo where c1='d1'and c3='d3' order by c2;


order by排序使用到索引和沒使用到索引的情況


實例五:

explain select * from t_demo where c1='d1'and c4='d4' order by c1,c2;


條件列包含沒有索引的列,出現(xiàn)了Using filesort


實例六:

explain select * from t_demo where c1='d1'and c4='d4' group by c1,c2;


性能非常差的場景,同時出現(xiàn)了Using temporary和Using filesort



總結(jié)


1. 兩種方式的排序filesort和index,Usingindex是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。


2. order by滿足兩種情況會使用Using index。

1)order by語句使用索引最左前列。

2)使用where子句與order by子句條件列組合滿足索引最左前列。


3. 盡量在索引列上完成排序,遵循索引建立(索引創(chuàng)建的順序)時的最佳左前綴法則。


4. group by與order by很類似,都是先排序后分組,遵照索引創(chuàng)建順序的最佳左前綴法則。



—————END—————



喜歡本文的朋友,歡迎關(guān)注公眾號?程序員小灰,收看更多精彩內(nèi)容

      
點個[在看],是對小灰最大的支持!


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉