淺談MySQL的索引(2)

????上一篇我們從索引的存儲(chǔ)結(jié)構(gòu)分析吸重,說(shuō)到了B Tree索引、Hash索引歪今、FULLTEXT全文索引嚎幸。這一期,我們?cè)趶钠渌麑哟螌W(xué)習(xí)洗索引彤委。


一鞭铆、前期回顧

  • 從索引存儲(chǔ)結(jié)構(gòu)劃分:B Tree索引、Hash索引焦影、FULLTEXT全文索引以及R Tree索引

  • 從應(yīng)用層次劃分:普通索引、唯一索引封断、主鍵索引斯辰、復(fù)合索引

  • 從鍵值劃分:主鍵、輔助

  • 從數(shù)據(jù)存儲(chǔ)以及索引邏輯關(guān)系劃分:聚集索引坡疼、非聚集索引


  • 二彬呻、索引的分類


    2.1、普通索引

    ????????普通索引既我們平時(shí)常用的索引柄瑰,默認(rèn)使用的是BTree闸氮。

    ALTER?TABLE?`user`ADD?INDEX?`index_userNm`?(`username`)?USING?BTREE?COMMENT?'用戶名索引';--?或者ALTER?TABLE?`user`ADD?INDEX?`index_userNm`?(`username`);

    2.2、唯一索引

    ????????與普通索引類似教沾,不同的點(diǎn)在于:索引的值必須唯一蒲跨,允許有空值。換句話說(shuō)?某種程度上說(shuō)的就是表中索引鎖標(biāo)記的唯一列授翻。

    ALTER?TABLE?`user`?ADD?UNIQUE?INDEX?`index_un_id`(`id`);

    主鍵索引

    ????????與唯一索引的區(qū)別就是索引標(biāo)記的列不允許有空值或悲,換句話說(shuō)就是主鍵列上加的索引孙咪。

    ALTER?TABLE?`user`?ADD?PRIMARY?KEY?(`id`);

    2.3、復(fù)合索引

    ????????又名聯(lián)合索引巡语,也是我們比較常用的索引類型之一翎蹈。在數(shù)據(jù)表的2列或>2列共同組成的索引。而上面我們說(shuō)的普通索引男公、唯一索引荤堪、主鍵索引又叫單一索引。顧名思義是指索引列只有一列枢赔,而用戶可以在多個(gè)列上建立索引澄阳,這種索引就叫復(fù)合索引,也叫組合索引糠爬、聯(lián)合索引寇荧,復(fù)合索引可以代替多個(gè)單一索引,相遇多個(gè)單一索引执隧,復(fù)合索引所需的開(kāi)銷更小揩抡。


    在這里復(fù)合索引還有個(gè)小小的區(qū)分:窄索引、寬索引

    • 窄索引:指索引列為1-2列的索引

    • 寬索引:指索引列超過(guò)2列的索引

    ??索引設(shè)計(jì)原則:能用窄索引不用寬索引镀琉,因?yàn)檎饕冉M合索引更有效


    ? ?值得我們重點(diǎn)關(guān)注的是:

  • 需要加索引的字段峦嗤,要在where條件中。

  • 數(shù)據(jù)量少的字段不需要加索引屋摔。最窄的字段放在鍵的左邊烁设。

  • 如果where條件中是OR關(guān)系,必須所有的or條件都必須是獨(dú)立索引钓试,否則加索引不起作用装黑。見(jiàn):mysql關(guān)于or的索引問(wèn)題

  • 左匹配原則。

  • 只要列中包含有NULL值都將不會(huì)被包含在索引中弓熏,復(fù)合索引中只要有一列含有NULL值恋谭,那么這一列對(duì)于此復(fù)合索引就是無(wú)效的。所以我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)時(shí)不要讓字段的默認(rèn)值為NULL挽鞠。


  • eg:

    假設(shè)某個(gè)表有一個(gè)聯(lián)合索引(c1,c2,c3,c4)以下選項(xiàng)哪些字段使用了該索引:
    A where c1=x and c2=x and c4>x and c3=x
    B where c1=x and c2=x and c4=x order by c3
    C where c1=x and c4= x group by c3,c2
    D where c1=? and c5=? order by c2,c3
    E where c1=? and c2=? and c5=? order by c2,c3


    接下來(lái)借用上面的例子疚颊,我們求證一下:

  • 首先創(chuàng)建表:

  • CREATE?TABLE?t(??c1?CHAR(1)?not?null,??c2?CHAR(1)?not?null,??c3?CHAR(1)?not?null,??c4?CHAR(1)?not?null,??c5?CHAR(1)?not?null)ENGINE?myisam?CHARSET?UTF8;

  • 創(chuàng)建索引:

  • alter?table?t?add?index?c1234(c1,c2,c3,c4);

  • 隨機(jī)搞兩條數(shù)據(jù):

  • insert?into?t?VALUES('1','1','1','1','1'),('2','2','2','2','2')

  • 使用MySql Explain開(kāi)始分析題目結(jié)果:

  • A 選項(xiàng):where c1=x and c2=x and c4>x and c3=x



    說(shuō)明下:UTF-8 編碼,一個(gè)索引的長(zhǎng)度為3信认,如上圖我們可以看到材义,c1,c2,c3,c4均使用到了該索引。

    但是如果我們將查詢條件調(diào)整下或者去掉一個(gè)嫁赏,索引又是怎么使用的呢:





    由上面4個(gè)圖可以看出其掂,我們分別調(diào)整了各個(gè)列的位置居兆,使用>和使用>的位置拘央,發(fā)現(xiàn)索引都是正常使用的,所以可以得出:

  • 使用“<” / “>”并不影響索引的選擇

  • where條件和創(chuàng)建索引的列保持一致時(shí),條件的位置(順序)并不影響索引的選擇腐螟。


  • 但是争舞,如果我們對(duì)A組where條件做些調(diào)整呢坑鱼?




    當(dāng)我們刪除分別其中一個(gè)條件c1酿矢、c2、c3后盔夜,發(fā)現(xiàn)使用索引的個(gè)數(shù)也發(fā)生了變化负饲。得出結(jié)論:

  • 當(dāng)使用復(fù)合索引時(shí),沒(méi)有使用第一個(gè)復(fù)合索引喂链,不觸發(fā)索引的使用

  • 使用復(fù)核索引時(shí)返十,索引的選擇與where的條件順序和索引建立時(shí)的順序是否一致存在關(guān)系,當(dāng)順序中斷時(shí)椭微,后續(xù)的索引列將不被選擇洞坑。


  • 如果我們對(duì)A組where條件做些調(diào)整呢?








    當(dāng)我們使用or蝇率,或者like時(shí)迟杂,通過(guò)上面4張圖可以清醒的得出:

  • 當(dāng)使用or時(shí),不會(huì)使用索引

  • 當(dāng)條件順序與索引創(chuàng)建順序一致本慕,且使用?“l(fā)ike”?/?“l(fā)ike%”時(shí)排拷,索引可以正常被選中

  • 當(dāng)條件順序與索引創(chuàng)建順序一致,且使用 “%like%”锅尘,索引無(wú)法被選中

  • 當(dāng)條件順序與索引創(chuàng)建順序不一致時(shí)监氢,且第一個(gè)條件不是索引創(chuàng)建時(shí)的首列,則無(wú)法選中索引


  • B選項(xiàng):where c1=x and c2=x and c4=x order by c3



    通過(guò)上圖可以發(fā)現(xiàn)藤违,key_len長(zhǎng)度說(shuō)明c1浪腐,c2字段用到了該索引,Extra顯示并沒(méi)有使用臨時(shí)表進(jìn)行排序顿乒,說(shuō)明排序是使用了索引的牛欢,但并沒(méi)有計(jì)算在key_len值中,也沒(méi)有起到連接c4的作用淆游,說(shuō)明索引到c3這里是斷掉的。

    排序其實(shí)是利用聯(lián)合索引直接完成了的隔盛,即:使用了c1234聯(lián)合索引犹菱,就已經(jīng)使得c1下c2,c2下c3吮炕,c3下c4是有序的了腊脱,所以實(shí)際是排序利用了索引,c3字段并沒(méi)有使用該索引龙亲。


    C選項(xiàng):where c1=x and c4= x group by c3,c2



    通過(guò)上面兩圖陕凹,能看出使用group by 一般先生成臨時(shí)文件悍抑,再進(jìn)行排序,但是字段順序?yàn)閏2杜耙,c3時(shí)搜骡,并沒(méi)有用臨時(shí)表進(jìn)行排序,而是利用索引排序好的佑女;當(dāng)group by字段為c3记靡,c2時(shí),由于與索引字段順序不一致团驱,所以分組和排序并沒(méi)有利用到索引摸吠。


    D選項(xiàng):where c1=? and c5=? order by c2,c3


    通過(guò)此圖可以看出 order by 和group by 類似,字段順序與索引一致時(shí)嚎花,會(huì)使用索引排序寸痢;字段順序與索引不一致時(shí),不使用索引紊选。


    E選項(xiàng):where c1=? and c2=? and c5=? order by c2,c3


    其實(shí)選項(xiàng)E的結(jié)果分析在上述ABCD的結(jié)果中都分析過(guò)了啼止,這里只有c1,c2字段使用了該索引丛楚。

    綜上所述問(wèn)題答案:

    ????A:四個(gè)字段均使用了該索引

    ????B:c1族壳,c2字段使用了該索引

    ????C:c1字段使用該索引

    ????D:c1字段使用該索引

    ????E:c1,c2字段使用了該索引

    三趣些、小結(jié):

  • 索引的最左原則(左前綴原則)仿荆,如(c1,c2,c3,c4....cN)的聯(lián)合索引,

  • where 條件按照索引建立的字段順序來(lái)使用(不代表and條件必須按照順序來(lái)寫)坏平,

  • 如果中間某列沒(méi)有條件拢操,或使用like會(huì)導(dǎo)致后面的列不能使用索引。

  • 索引也能用于分組和排序舶替,分組要先排序令境,在計(jì)算平均值等等。所以在分組和排序中顾瞪,如果字段順序可以按照索引的字段順序舔庶,即可利用索引的有序特性。


  • 不知不覺(jué)寫到這又有 2.5k 多字了陈醒,本期我們就寫到這里惕橙,下期我們繼續(xù)

    探討索引。

    …………………………………分割線……………………………

    不積跬步钉跷,無(wú)以至千里弥鹦;不積小流,無(wú)以成江海爷辙。

    關(guān)注我彬坏,每天分享一些小知識(shí)點(diǎn)朦促。分享自己的小心得,包含但不限于初栓始、中务冕、高級(jí)面試題呦!;焯稀洒疚!

    我都墨跡這么半天了 ,你不點(diǎn)關(guān)注坯屿,不點(diǎn)贊油湖,不收藏,還不轉(zhuǎn)發(fā)领跛,你想干啥7Φ隆!吠昭!

    最后編輯于
    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
    • 序言:七十年代末喊括,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子矢棚,更是在濱河造成了極大的恐慌郑什,老刑警劉巖,帶你破解...
      沈念sama閱讀 218,122評(píng)論 6 505
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒲肋,死亡現(xiàn)場(chǎng)離奇詭異蘑拯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)兜粘,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 93,070評(píng)論 3 395
    • 文/潘曉璐 我一進(jìn)店門申窘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人孔轴,你說(shuō)我怎么就攤上這事剃法。” “怎么了路鹰?”我有些...
      開(kāi)封第一講書人閱讀 164,491評(píng)論 0 354
    • 文/不壞的土叔 我叫張陵贷洲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我晋柱,道長(zhǎng)恩脂,這世上最難降的妖魔是什么? 我笑而不...
      開(kāi)封第一講書人閱讀 58,636評(píng)論 1 293
    • 正文 為了忘掉前任趣斤,我火速辦了婚禮,結(jié)果婚禮上黎休,老公的妹妹穿的比我還像新娘浓领。我一直安慰自己玉凯,他們只是感情好,可當(dāng)我...
      茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
    • 文/花漫 我一把揭開(kāi)白布联贩。 她就那樣靜靜地躺著漫仆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泪幌。 梳的紋絲不亂的頭發(fā)上盲厌,一...
      開(kāi)封第一講書人閱讀 51,541評(píng)論 1 305
    • 那天,我揣著相機(jī)與錄音祸泪,去河邊找鬼吗浩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛没隘,可吹牛的內(nèi)容都是我干的懂扼。 我是一名探鬼主播,決...
      沈念sama閱讀 40,292評(píng)論 3 418
    • 文/蒼蘭香墨 我猛地睜開(kāi)眼右蒲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼阀湿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瑰妄,我...
      開(kāi)封第一講書人閱讀 39,211評(píng)論 0 276
    • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤陷嘴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后间坐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灾挨,經(jīng)...
      沈念sama閱讀 45,655評(píng)論 1 314
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
    • 正文 我和宋清朗相戀三年眶诈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涨醋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
      茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
    • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逝撬,死狀恐怖浴骂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宪潮,我是刑警寧澤溯警,帶...
      沈念sama閱讀 35,684評(píng)論 5 347
    • 正文 年R本政府宣布,位于F島的核電站狡相,受9級(jí)特大地震影響梯轻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尽棕,卻給世界環(huán)境...
      茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
    • 文/蒙蒙 一喳挑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦伊诵、人聲如沸单绑。這莊子的主人今日做“春日...
      開(kāi)封第一講書人閱讀 31,894評(píng)論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搂橙。三九已至,卻和暖如春笛坦,著一層夾襖步出監(jiān)牢的瞬間区转,已是汗流浹背。 一陣腳步聲響...
      開(kāi)封第一講書人閱讀 33,012評(píng)論 1 269
    • 我被黑心中介騙來(lái)泰國(guó)打工版扩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留废离,地道東北人。 一個(gè)月前我還...
      沈念sama閱讀 48,126評(píng)論 3 370
    • 正文 我出身青樓资厉,卻偏偏與公主長(zhǎng)得像厅缺,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宴偿,可洞房花燭夜當(dāng)晚...
      茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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