MySQL執(zhí)行計(jì)劃解讀

一)基本內(nèi)容

1. 查看
  • desc ...
  • explain ...
2. 計(jì)劃類(lèi)型【參數(shù)】
  • mysql5.6:
    desc extended | format=traditional ...
    --extended 查看優(yōu)化過(guò)的SQL語(yǔ)句

  • mysql5.7:
    desc extended | format=traditional ...

  • mysql8.0:
    desc format=tree ...
    --tree 因?yàn)閔ash,所以用tree 可以客觀(guān)體現(xiàn) join方式
    show warnings\G;

3. 執(zhí)行計(jì)劃關(guān)鍵詞
  • id: --單純的查詢(xún),尖都是從1開(kāi)始烫扼,子查詢(xún)都會(huì)使id遞增曙求。
  • select_type: --simple沒(méi)有關(guān)聯(lián)查詢(xún)
  • type: --
  • possible_keys:--可用的索引
  • key: --使用的索引
  • ref: --驅(qū)動(dòng)表的關(guān)聯(lián)字段
  • rows: --預(yù)估行數(shù)
  • filtered: -- 100是沒(méi)有二次過(guò)濾
  • extra: --
4. 驅(qū)動(dòng)表:

選擇驅(qū)動(dòng)表時(shí),應(yīng)選結(jié)果集小映企,因?yàn)殡p循環(huán)外循環(huán)(驅(qū)動(dòng)表為外循環(huán))次數(shù)越少悟狱,越省資源,進(jìn)而查詢(xún)速度也相對(duì)快些卑吭。
驅(qū)動(dòng)表是跟最后一個(gè)join開(kāi)始執(zhí)行芽淡,然后倒數(shù)第二個(gè),倒數(shù)第三個(gè)豆赏。。富稻。以此類(lèi)推掷邦。


二)select_type

1. simple:--不使用union或者subquery的簡(jiǎn)單query。
  • mysql5.7之后有 derived_merge

    • 查:show variables like '%opt%'; optimizer_search_switch:derived_merge=on--子查詢(xún)合并(視圖合并)
    • 關(guān)閉:set session optimizer_search_switch='derived_merge=off';
  • limit:--用在優(yōu)化時(shí)椭赋,使用時(shí)標(biāo)量子查詢(xún)視圖不合并情況之一抚岗。

2. subquery:標(biāo)量子查詢(xún),位于from之前哪怔。
  • 標(biāo)量子查詢(xún)宣蔚,跟外部表沒(méi)啥關(guān)聯(lián)向抢,相當(dāng)于一個(gè)常數(shù)。
  • 子查詢(xún)不要嵌套子查詢(xún)胚委,影響性能挟鸠。
3. dependent subquery(標(biāo)量子查詢(xún),子查詢(xún)都有可能亩冬。特別注意艘希,表的別名不要重復(fù)。)
  • 必須依附于外面的值
  • scala subquery(標(biāo)量子查詢(xún) )
  • exists
    • mysql5.7及之前 depentend subquery
    • mysql8.0.16之后的版本硅急,exists的語(yǔ)句會(huì)轉(zhuǎn)換成in,執(zhí)行計(jì)劃為simple覆享,如何使exists不改寫(xiě)為in,使執(zhí)行計(jì)劃為depentend subquery?
      select straight_join * from t1 exists (select 1 from t2 where t1.id=t2.id);
4. primary:
  • 用union
  • 或者用subquery
5. union:
  • union result去重復(fù)值
  • 生成臨時(shí)表
    • max_heap_table_size
    • tmp_table_size

查詢(xún)時(shí) 使用的是union营袜。mysql5.6版本union all操作也去重撒顿。

6. union all:是union all操作,不去重荚板。
  • 5.6 union result 產(chǎn)生臨時(shí)表
  • 5.7 不產(chǎn)生臨時(shí)表
7. derived:派生表凤壁,位于from后 子查詢(xún)。
  • derived是生成在內(nèi)存或臨時(shí)表空間中的啸驯。

    • max_heap_table_size
    • tmp_table_size
  • derived 當(dāng)作驅(qū)動(dòng)表時(shí)客扎,要點(diǎn)是要減少數(shù)據(jù)量為目的。

  • derived 當(dāng)作被驅(qū)動(dòng)表時(shí)罚斗,產(chǎn)生auto_key索引(當(dāng)條件字段大于767時(shí)徙鱼,不產(chǎn)生auto_key),也要以減少數(shù)據(jù)量為目的针姿。

  • 不視圖合并的情況:

    1. union/union all
      from (select ...from ... union select ... from ...)
    2. group
      from (select ...from... group by )
    3. distinct
      from (select distinct(xxx) from ...)
    4. 聚合函數(shù)
      from (select min(x),max(x),sum(x)... from...)
    5. limit
      from (select... from ... limit ...)
    6. @
      • select c1,(select @a:=0) x from ...
8. materialized:semi join,產(chǎn)生auto_key
  • 使用in的時(shí)候
  • 使用exists的時(shí)候 袱吆??有可能
  • 用hint強(qiáng)制使用materialized
    select /*+ semi join(@sub materialization) / * from t1 where t1.c1 in(select /+ QB_NAME(sub) */) c2 from t2);

三)type

1. const
  • 出現(xiàn)在單表距淫、驅(qū)動(dòng)表的pk绞绒、unique, 返回一條數(shù)據(jù)榕暇。
2. eq_ref
  • join時(shí)蓬衡,被驅(qū)動(dòng)表連接條件有PK或unique時(shí)。
3. ref
  • 索引列作為 "=" 值條件運(yùn)算時(shí)
  • 當(dāng)有聯(lián)合索引跟單列索引時(shí)彤枢,可能會(huì)錯(cuò)用索引狰晚,可以用 force index(xx)解決
4. range
  • 范圍查詢(xún),只能用到驅(qū)動(dòng)表
5. index 絕大部分情況下是優(yōu)化對(duì)象缴啡,相當(dāng)于索引全掃描
  1. 不能使用range const ref時(shí)壁晒;
  2. 只查詢(xún)索引列,不回表時(shí)业栅;
  3. 使用索引進(jìn)行排序或聚合
  4. 聯(lián)合索引中秒咐,前導(dǎo)列不在where條件中谬晕,且查詢(xún)列在索引中。
  5. group by 字段 在索引或pk中
6. all
  • 結(jié)果集超過(guò)一半的量的查詢(xún)效果更好携取。
  • 沒(méi)有索引時(shí)攒钳,或類(lèi)型轉(zhuǎn)換時(shí)。
  • like 字符 可走索引
    • c1 like 'li%';
  • all 關(guān)鍵字在執(zhí)行計(jì)劃中的位置越往下歹茶,出問(wèn)題的情況越高夕玩。

四)possible_keys:可用的索引

  • 列出所有的索引
  • 列出auto_key
    • 當(dāng)子查詢(xún)當(dāng)作被驅(qū)動(dòng)表時(shí),字段長(zhǎng)度不超過(guò)767時(shí)惊豺,自動(dòng)生成auto_key燎孟。
    • auto_key 在臨時(shí)表,控制臨時(shí)表相關(guān)參數(shù):
      • tmp_table_size
      • max_heap_table_size

五)key:實(shí)際使用的索引

  • 查索引 show index from tb_name
    • cardinality 去掉重復(fù)值的預(yù)估行數(shù)尸昧,參數(shù):innodb_stats_persistent_sample_pages
    • visible

六)key_len 使用到的索引長(zhǎng)度


七)ref: --驅(qū)動(dòng)表的關(guān)聯(lián)字段


八)rows: --預(yù)估行數(shù)


九)filtered:二次過(guò)濾預(yù)估值揩页,從引擎拿到數(shù)據(jù)再加工的比率,100是沒(méi)有二次過(guò)濾烹俗。


九)extra:

1. distinct
  • join 中 兩表關(guān)聯(lián)爆侣,有一條符合記錄即停止,有點(diǎn)像semi join
  • 條件:
    • select 必須有distinct 關(guān)鍵字
    • select 只能含有驅(qū)動(dòng)表字段
      • 可以使用straight_join強(qiáng)制第一個(gè)表為驅(qū)動(dòng)表
2. select tables optimized away
  • 8.0之前 聚合函數(shù)出現(xiàn)時(shí)
3. using filesort
  • 進(jìn)行order by ,group by(8.0之后不排序) 且沒(méi)使用索引時(shí)幢妄;
  • order by 時(shí)兔仰,select的列都會(huì)寫(xiě)入臨時(shí)表空間
4. using index
  • 只使用索引,不回表
  • 一種思路蕉鸳,可把常用列創(chuàng)建索引乎赴,達(dá)到垂直分表的效果。
5. using temporary
  • 中間結(jié)果會(huì)使用臨時(shí)表,但無(wú)法判斷在內(nèi)存中潮尝,還是硬盤(pán)中榕吼。(設(shè)置參數(shù) temp_table_max_ram=1 測(cè)試)
  • order by、group by 時(shí)勉失;
  • 產(chǎn)生derived(派生表)時(shí)
6. using where
  • 從存儲(chǔ)引擎中拿到一些數(shù)據(jù)羹蚣,然后再過(guò)濾。
7. using index condition(減少回表量)
  • 必須二級(jí)索引乱凿,且有一部分無(wú)法使用索引時(shí)顽素。
  • set session optimize_switch="index_condition_pushdown=on"
8. using mrr
  • 二級(jí)索引取得PK之后,對(duì)PK進(jìn)行排序徒蟆,減少隨機(jī)IO戈抄。
  • set session optimize_switch='mrr_cost_based=off'
9. range checked for each record
  • 這時(shí)type肯定是all,沒(méi)用上索引
10. using join buffer:(block nested loop)
  • 大部分情況是優(yōu)化對(duì)象
  • 適用于被驅(qū)動(dòng)表沒(méi)有索引時(shí)且數(shù)據(jù)量較小時(shí)。
  • set session optimizer_switch='block_nested_loop=on'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末后专,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子输莺,更是在濱河造成了極大的恐慌戚哎,老刑警劉巖裸诽,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異型凳,居然都是意外死亡丈冬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)甘畅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埂蕊,“玉大人,你說(shuō)我怎么就攤上這事疏唾⌒钛酰” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵槐脏,是天一觀(guān)的道長(zhǎng)喉童。 經(jīng)常有香客問(wèn)我,道長(zhǎng)顿天,這世上最難降的妖魔是什么堂氯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮牌废,結(jié)果婚禮上咽白,老公的妹妹穿的比我還像新娘。我一直安慰自己鸟缕,他們只是感情好晶框,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著叁扫,像睡著了一般三妈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莫绣,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天畴蒲,我揣著相機(jī)與錄音,去河邊找鬼对室。 笑死模燥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掩宜。 我是一名探鬼主播蔫骂,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼牺汤!你這毒婦竟也來(lái)了辽旋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎补胚,沒(méi)想到半個(gè)月后码耐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溶其,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年骚腥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓶逃。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡束铭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厢绝,到底是詐尸還是另有隱情契沫,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布代芜,位于F島的核電站埠褪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挤庇。R本人自食惡果不足惜钞速,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫡秕。 院中可真熱鬧渴语,春花似錦、人聲如沸昆咽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掷酗。三九已至调违,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泻轰,已是汗流浹背技肩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浮声,地道東北人虚婿。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像泳挥,于是被迫代替她去往敵國(guó)和親然痊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354