MySQL索引及執(zhí)行計劃

索引的簡介

類似于一本書的目錄倾贰,起到優(yōu)化查詢的內(nèi)容

索引的分類

  • BTREE
  • RTREE
  • Hash innodb中自適應hash算法县习,自動維護
  • fullText:全文索引(實現(xiàn)和es差不多的功能沟启,把一句話拆分成一個個詞三娩,但效果不怎么理想鸿脓,因為MySQL是結構化存儲抑钟,es是json格式存儲)
  • Gis:地理位置索引(學的mongodb涯曲,一般存儲地圖)

BTREE 索引的演變

BTREE 索引原理圖.png

上層節(jié)點存放下層節(jié)點的最小值,即根節(jié)點存放枝節(jié)點的最小值在塔,枝節(jié)點存放葉子節(jié)點的最小值
BTREE+樹在葉子節(jié)點增加了雙向指針幻件,BTREE*是在葉子節(jié)點和枝節(jié)點增加雙向指針

輔助索引(二級索引)

1 .管理員選擇一個列建立輔助索引
2 .MySQL自動將此列取出來
3 .將此列值排好序(從小到大)
4 .將排好的數(shù)據(jù)均勻的分配到葉子節(jié)點上
5 .生成枝節(jié)點和跟節(jié)點
6 .在葉子節(jié)點中的值,都會存儲主鍵ID

聚集索引

1 .如果用的是輔助索引心俗,拿到輔助索引葉子節(jié)點的聚集索引的ID值傲武,去遍歷,然后去查找數(shù)據(jù)
2 .MySQL會自動選擇主鍵城榛,作為聚集索引揪利,沒有主鍵會選擇唯一主鍵,如果都沒有會生成隱藏的
3 .MySQL進行存儲數(shù)據(jù)時狠持,會按照聚集索引列的值的順序疟位,有序的存儲數(shù)據(jù)行
4 .聚集索引直接將原表數(shù)據(jù)頁阀坏,作為葉子節(jié)點此熬,然后提取聚集索引列向上生成枝節(jié)點和根節(jié)點

輔助索引細分

  • 單列輔助索引
  • 聯(lián)合索引(覆蓋索引)【重要】
  • 唯一索引

索引樹高度問題

索引樹高度一般越低越好,一般維持在3-4層最佳

數(shù)據(jù)行多的時候

采用分布式架構礁芦,進行分庫分表

字段長度

盡量選擇正勒,字符串長度短的列作為索引列得院,如果業(yè)務不允許,則采用前綴索引

數(shù)據(jù)類型

char 和varchar的選擇章贞,enum的選擇

關于索引操作的問題

查詢索引

desc 表名祥绞;
PRI ===> 主鍵索引(聚集索引)
MUL===> 普通索引(輔助)
UNI====> 唯一索引
show index from 表名;   //查的比較全

創(chuàng)建索引

# 創(chuàng)建普通索引
alter table city add index idx_name(name)
這也是屬于DDL語句,也會鎖表鸭限。在業(yè)務不繁忙時間做蜕径,或者使用pt-osc工具
# 創(chuàng)建聯(lián)合索引
alter table city add index idx_c_p(countrycode,population);
# 建立唯一索引
alter table city add index uniqe uniqx_dis(district);
注: 唯一索引列的值必須是唯一的,不能有重復值
# 建立前綴索引
alter table city add index idx_dis(district(5))

執(zhí)行計劃分析

作用

將優(yōu)化器選擇后的執(zhí)行計劃败京,給截取出來兜喻,給管理員判斷執(zhí)行效率。(在語句執(zhí)行之前赡麦,把執(zhí)行計劃拿到)

獲取執(zhí)行計劃

desc sql語句;
explain sql語句朴皆;

分析執(zhí)行計劃

table

表名,如果是多表連接隧甚,可能一個表出現(xiàn)問題车荔,此時這個table就有作用了

type 重要

查詢類型,MySQL查詢中有兩大類型 全表掃描和索引掃描
索引掃描的級別為: index,range,ref,eq_ref,const(system),null 從左到右的性能依次變好

  • index: 全索引掃描(整個索引列都進行遍歷)desc select id from ctiy
  • range: 索引范圍掃描(>,<,>=,<=,between and, in,and ,or,like)desc select id from city where id <100; desc select * from city countrycode='CHN' and countrycode='USA' like,>,<,>=,<=的性能要比and,or,between and,in 好戚扳,因為MySQL采用BTREE* 樹索引,枝節(jié)點和葉子節(jié)點都有雙向指針族吻。and,or,in,between and 都用不了雙向指針帽借,一般要把and和or改寫為union all對于輔助索引來說珠增,!=和not in 不走索引,但對于主鍵來講 !=和not in 等語句是走range
  • ref: 輔助索引等值查詢 desc select * from city where countrycode='CHN'
  • eq_ref: 在多表連接時,子表使用主鍵列或唯一鍵作為連接條件A join B on A.x = B.y,B作為子表砍艾,B.y為主鍵列時蒂教,為eq_ref ,A為驅動表脆荷,是不走索引的desc select b.name,a.name,a.population from city as a join country as b on a.countrycode=b.code where a.population<100
  • const(system): 兩個一樣凝垛,當主鍵或者唯一鍵的等值查詢時desc select * from city where id=2
  • NULL: 所查詢的數(shù)據(jù),在數(shù)據(jù)中沒有時蜓谋。

possible_key

可能會用到的key

key

最后用到的key

key_len

索引覆蓋長度梦皮,當前列可以為空時,其中有一個字節(jié)標識是否為空

單列索引長度

注: 所有列的可以為空桃焕,utf8mb4的字符集

varchar(20) 說明

  • 能存任意20個字符
  • 不管存儲的字符剑肯,數(shù)字,中文观堂,都是1個字符最大預留長度是4字節(jié)
  • 對于中文让网,1個字符占4個字節(jié)
  • 對于數(shù)字和字母,1個字符實際占用大小是1個字節(jié)
  • select length(列名) from 表名 查看這一列师痕,每行的長度
int(5)   ===>   4+1 ==》  1 為標識該列是否為空
char(2) ===> 4+4+1  ==》 1 為標識該列是否為空
varchar(2) ===> 4+4+1+1+1 ===>   1 為標識該列是否為空  其余兩個1位開始位置和結束位置

聯(lián)合索引

add index idx(a,b,c,d)

  • 唯一值多的列放在左側
  • 只要我們將來的查詢溃睹,所有的列都是等值查詢,無關順序排序(a,b,c,d),(b,d,c,a),(a,b,d,c)……胰坟,因為優(yōu)化器自動將我們查詢條件進行排序了
  • 不連續(xù)的部分條件
cda  ==> a,c,d 只走a索引因篇,因b沒有了。建立聯(lián)合索引的時候是按照a,b,c,d的順序建立的===>優(yōu)化建議腕铸,可以刪除原來索引惜犀,在新建一個cda的索引。(在業(yè)務支持的情況下)
所有列相同的不同的索引會相互影響狠裹。
  • 在where查詢中如果出現(xiàn)不等值(>,<,>=,<=,like)
    add index idx(a,b,c,d)
…… where  a=1 and b>3 and c=2 and d=5   如果出現(xiàn)不等值查詢虽界,索引只會卡在b那,即走a和b的索引
優(yōu)化建議:
1 .把不等值查詢放在最后面(不過優(yōu)化器會自動排序)
2 .更改聯(lián)合索引的順序涛菠,刪了重新建(重點)
  • 對于多子句的情況莉御,應用聯(lián)合索引
    需要按照語句的執(zhí)行順序,建立聯(lián)合索引
    為什么要用聯(lián)合索引俗冻,而不是單列索引礁叔。因為MySQL默認只會使用一種索引

Extra

額外執(zhí)行的命令
重點: using filesort額外的排序 ,出現(xiàn)此語句迄薄,說明select排序的條件列中琅关,沒有合理的用到索引,涉及到排序的條件order by,group by,distinct,union

索引的應用規(guī)范

建立索引的原則(DBA的運維規(guī)范)

  • 建表必須要有主鍵,一般是無關列讥蔽,自增長
  • 經(jīng)常為where條件列 order by,group by,join on,distinct的條件
  • 最好使用唯一值多的列涣易,做為聯(lián)合索引的最左列画机,其余的按照優(yōu)化細節(jié)來做
  • 列值較長的索引列,我們建議使用前綴索引
  • 降低索引條目新症,一方面不要創(chuàng)建沒用的索引步氏,不常使用的索引進行清除,percona toolkit(xxx),pt-duplicate-key-checker ---檢查數(shù)據(jù)庫重復索引
  • 索引維護徒爹,要避開業(yè)務繁忙期
  • 小表不建索引

不走索引的情況(開發(fā)規(guī)范)

  • 沒用查詢條件荚醒,或者條件沒用建立索引select * from city,select * from city where 1=1
  • 查詢結果集是原表的絕大部分數(shù)據(jù),應該是25%以上
  • 索引本身失效隆嗅,統(tǒng)計數(shù)據(jù)不真實
  • 查詢條件調用函數(shù)在索引列上界阁,或者對索引列進行運算,運算包括(+,-,*,/,!)等
    desc select * from city where id-99=1
  • 隱式轉換導致索引失效
CREATE TABLE ttt(id INT,num CHAR(2))
INSERT INTO ttt VALUES(1,2),(2,'3');
ALTER TABLE ttt ADD INDEX idx(num)
DESC SELECT * FROM ttt WHERE num=2   //不走索引
DESC SELECT * FROM ttt WHERE num='2' //走索引
num=2 ,MySQL會通過函數(shù)將2 轉換為字符串類型,根據(jù)上一條榛瓮,索引列有函數(shù)铺董,將不會走索引
  • <>(相當于!),not ni 不走索引(輔助索引)
  • like '%aa' ,百分號在前面時
  • 聯(lián)合索引 ???

聯(lián)合索引禀晓,意外情況

將表中所有列建立聯(lián)合索引精续,每個列作為查詢條件都會走索引

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市粹懒,隨后出現(xiàn)的幾起案子重付,更是在濱河造成了極大的恐慌,老刑警劉巖凫乖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件确垫,死亡現(xiàn)場離奇詭異,居然都是意外死亡帽芽,警方通過查閱死者的電腦和手機删掀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來导街,“玉大人披泪,你說我怎么就攤上這事“峁澹” “怎么了款票?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泽论。 經(jīng)常有香客問我艾少,道長,這世上最難降的妖魔是什么翼悴? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任缚够,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘潮瓶。我一直安慰自己陶冷,他們只是感情好钙姊,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布毯辅。 她就那樣靜靜地躺著,像睡著了一般煞额。 火紅的嫁衣襯著肌膚如雪思恐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天膊毁,我揣著相機與錄音胀莹,去河邊找鬼。 笑死婚温,一個胖子當著我的面吹牛描焰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播栅螟,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼荆秦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了力图?” 一聲冷哼從身側響起步绸,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吃媒,沒想到半個月后瓤介,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡赘那,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年刑桑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片募舟。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡祠斧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胃珍,到底是詐尸還是另有隱情梁肿,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布觅彰,位于F島的核電站吩蔑,受9級特大地震影響,放射性物質發(fā)生泄漏填抬。R本人自食惡果不足惜烛芬,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赘娄,春花似錦仆潮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至揍堰,卻和暖如春鹏浅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屏歹。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工隐砸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蝙眶。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓季希,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幽纷。 傳聞我的和親對象是個殘疾皇子式塌,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容