MySQL索引使用細(xì)節(jié)

MySQL索引使用細(xì)節(jié)

這里不介紹MySQL索引是什么,僅總結(jié)索引使用的一些注意事項(xiàng)

索引的代價(jià)

我們知道了B+樹(shù)的索引原理之后,也知道了表中的數(shù)據(jù)都是在聚簇索引上的神郊,同時(shí)就是一顆B+樹(shù)。所有之后按其他建立的索引都是二級(jí)索引也叫非聚簇索引趾唱。

奇跡和魔法可不是免費(fèi)的

額外的索引當(dāng)然是有代價(jià)的涌乳,就像正常插入數(shù)據(jù)到聚簇索引中需要調(diào)整B+樹(shù)一樣,二級(jí)索引也有一模一樣的維護(hù)代價(jià)甜癞。那么毫無(wú)疑問(wèn)多余的索引存在:

  • 空間代價(jià)

    B+樹(shù)的一個(gè)節(jié)點(diǎn)在內(nèi)存中體現(xiàn)為一個(gè)頁(yè)夕晓,一頁(yè)的大小是16KB,如果索引很多悠咱,內(nèi)存中就會(huì)有更多的索引頁(yè)蒸辆。

  • 時(shí)間代價(jià)

    如果一個(gè)表頻繁的被修改,那么每次操作都要同步去修改B+樹(shù)中的索引值析既,索引越多需要同時(shí)維護(hù)的B+樹(shù)就越多躬贡,這顯然是一筆不小的代價(jià)

所以索引的建立不是越多越好,索引的選擇和使用更像是不斷權(quán)衡比較選擇相對(duì)最優(yōu)的選擇眼坏。

索引的匹配規(guī)則

簡(jiǎn)單說(shuō)明索引是如何創(chuàng)建的:當(dāng)以多個(gè)值建立聯(lián)合索引時(shí)拂玻,會(huì)按從左到右的順序進(jìn)行排序,也就是假如建立的索引為(A, B, C)宰译,

那么會(huì)先按列A進(jìn)行排序檐蚜,直到A值完全一樣,再依照B進(jìn)行排序囤屹,C同理熬甚。

索引這種規(guī)則也就解釋了最左前綴原則逢渔,當(dāng)希望使用索引時(shí)肋坚,應(yīng)該包含索引從左開(kāi)始的連續(xù)字段,因?yàn)椴樵兊捻樞蛞簿褪前唇⑺饕捻樞騺?lái)的。

提供幾個(gè)樣例來(lái)說(shuō)明:

  1. 字符串的模糊查詢是可以使用索引的(如果建立了的話)智厌,因?yàn)橐?code>name排序的過(guò)程中诲泌,實(shí)際是字符串的比較排序,而字符串的比較是從左到右一個(gè)個(gè)字符比較大小的來(lái)铣鹏,這和建立聯(lián)合索引的規(guī)則類似敷扫,比較好理解。
SELECT * FROM person_info WHERE name LIKE 'As%';
  1. 條件查詢中and連接的條件順序不影響索引的使用诚卸,SQL語(yǔ)句執(zhí)行前有查詢優(yōu)化器葵第。
SELECT * FROM person_info WHERE B = '1' and C = '2' and A = '0';

范圍值的匹配

如下的例子是可以使用索引的。

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

name排序之后合溺,對(duì)范圍內(nèi)的查詢相當(dāng)于分別查找兩個(gè)邊界值卒密,再去節(jié)點(diǎn)之間的鏈表值

不要忘記了B+樹(shù)的葉子節(jié)點(diǎn)是鏈表構(gòu)成的棠赛,有了邊界節(jié)點(diǎn)哮奇,在鏈表中遍歷就能找到期望數(shù)據(jù)了。

注意睛约!

范圍查詢可以使用索引是有要求的鼎俘,簡(jiǎn)單總結(jié)成一句話就是,范圍查詢的左邊都是精確查詢辩涝,而范圍查詢的右邊無(wú)法使用索引贸伐。解釋一下:

聯(lián)合索引是從左向右依次排序的,也就是只有在當(dāng)前比較列之前的完全相同的情況下怔揩,索引才是有效的棍丐。而左邊全是精確查詢就確保了 在范圍查詢前之前的列值是完全一樣的,就可以通過(guò)索引查找范圍沧踏,而找到一個(gè)范圍值之后剩下查詢的值就不能通過(guò)索引保證排序的(當(dāng)前在一個(gè)鏈表中假設(shè)按A進(jìn)行排序歌逢,而之后的B,C在單獨(dú)的一個(gè)A值下才是有序的,在這個(gè)列表中則表現(xiàn)為無(wú)序)翘狱。

范圍查找的索引狀況.png

關(guān)于關(guān)鍵字

  • Order By之后的順序遵循最左前綴原則秘案,同時(shí)如果要使用索引,順序必須一致潦匈,order by就是一個(gè)按提供鍵 順序排序的過(guò)程阱高。

    同時(shí)注意不要ASC,DESC混合使用。這樣也會(huì)導(dǎo)致索引效率低下茬缩。

  • WHERE中最好只有建立了索引的列赤惊,如果出現(xiàn)了未建立索引的列,那么查詢只能先將符合條件的記錄提取出來(lái)之后再進(jìn)行排序凰锡。

    同樣的未舟,WHERE條件中對(duì)索引列不要使用表達(dá)式函數(shù)圈暗,這會(huì)導(dǎo)致查詢將先對(duì)表達(dá)式進(jìn)行計(jì)算,構(gòu)建成新的列再排序裕膀。

  • Group by這點(diǎn)和Order By是完全類似的员串。

關(guān)于回表

回表同樣也是建立使用索引必須要權(quán)衡的代價(jià)之一≈缈福考慮這樣一個(gè)查詢

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

在范圍查找之后寸齐,要選擇出全部的數(shù)據(jù),那么就必然需要拿著索引中找到的主鍵去回表抄谐。

  • 訪問(wèn)二級(jí)索引使用順序I/O渺鹦,訪問(wèn)聚簇索引使用隨機(jī)I/O

需要回表的記錄越多蛹含,使用二級(jí)索引的性能就越差海铆。甚至可能因?yàn)榛乇磉^(guò)多,MySQL會(huì)將索引優(yōu)化成全表掃描挣惰。所以使用索引時(shí)盡可能指定需要的數(shù)據(jù)卧斟,而不要使用來(lái)表示,同時(shí)盡可能選擇索引中包含的列值*憎茂,這樣就不會(huì)進(jìn)行回表珍语。

覆蓋索引是一種解決回表的方式,但代價(jià)是存儲(chǔ)了相當(dāng)?shù)娜哂鄶?shù)據(jù)竖幔。

挑選索引

只列出幾條大致的規(guī)則:

  • 只為用于搜索板乙,排序,和分組的列創(chuàng)建索引

  • 考慮列的基數(shù)

    列的基數(shù)指某一列中不重復(fù)數(shù)據(jù)的個(gè)數(shù)拳氢。如果一個(gè)列中重復(fù)的數(shù)據(jù)過(guò)多募逞,基數(shù)過(guò)小(例如性別數(shù)據(jù)只有男馋评,女放接,基數(shù)為2)那么建立索引的效果就特別差,因?yàn)樵诠?jié)點(diǎn)中查找時(shí)幾乎沒(méi)有區(qū)分?jǐn)?shù)據(jù)的功能

  • 索引列的類型盡量小

    這是考慮到建立留特,維護(hù)索引的代價(jià)纠脾。以整數(shù)類型為例,有TINYINT蜕青、MEDIUMINT苟蹈、INTBIGINT這么幾種右核,它們占用的存儲(chǔ)空間依次遞增慧脱,我們這里所說(shuō)的類型大小指的就是該類型表示的數(shù)據(jù)范圍的大小。能表示的整數(shù)范圍當(dāng)然也是依次遞增贺喝,如果我們想要對(duì)某個(gè)整數(shù)列建立索引的話菱鸥,在表示的整數(shù)范圍允許的情況下宗兼,盡量讓索引列使用較小的類型,比如我們能使用INT就不要使用BIGINT采缚,能使用MEDIUMINT就不要使用INT

    • 數(shù)據(jù)類型越小针炉,查詢時(shí)比較操作越快

    • 數(shù)據(jù)類型越小挠他,索引所占空間更小扳抽,一個(gè)頁(yè)面中可以存放更多的索引數(shù)據(jù),變相減少了磁盤的I/O次數(shù)

  • 使用字符串值的前綴

    這點(diǎn)是針對(duì)字符串可能過(guò)長(zhǎng)的情況殖侵,理由和上面類似贸呢,為了減少查詢和維護(hù)時(shí)的代價(jià),僅以字符串前幾位進(jìn)行比較建立索引拢军。之后的值可以在一個(gè)小范圍內(nèi)遍歷查找楞陷,這樣犧牲了極小的性能省出了更多的空間和查找時(shí)間。

主鍵的選取

關(guān)于主鍵的選擇茉唉,一般MySQL會(huì)使用標(biāo)記為Unique的列構(gòu)建索引固蛾,如果沒(méi)有則會(huì)創(chuàng)建一個(gè)隱藏的自增列用于排序(在行格式,列結(jié)構(gòu)中提到過(guò))度陆。對(duì)于大多數(shù)情況來(lái)說(shuō)艾凯,主鍵最好選擇一個(gè)非業(yè)務(wù)的列,因?yàn)樽栽龅闹凳潜阌谠?code>頁(yè)中插入行數(shù)據(jù)的懂傀,如果不是順序的鍵很有可能數(shù)據(jù)插入過(guò)程中被分配在不同的頁(yè)趾诗,而插入新值后又需要不斷調(diào)整行數(shù)據(jù)的位置導(dǎo)致頁(yè)分裂之類的問(wèn)題,影響效率蹬蚁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恃泪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子犀斋,更是在濱河造成了極大的恐慌贝乎,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叽粹,死亡現(xiàn)場(chǎng)離奇詭異糕非,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)球榆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門朽肥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人持钉,你說(shuō)我怎么就攤上這事衡招。” “怎么了每强?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵始腾,是天一觀的道長(zhǎng)州刽。 經(jīng)常有香客問(wèn)我,道長(zhǎng)浪箭,這世上最難降的妖魔是什么穗椅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮奶栖,結(jié)果婚禮上匹表,老公的妹妹穿的比我還像新娘。我一直安慰自己宣鄙,他們只是感情好袍镀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著冻晤,像睡著了一般苇羡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鼻弧,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天设江,我揣著相機(jī)與錄音,去河邊找鬼攘轩。 笑死叉存,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撑刺。 我是一名探鬼主播鹉胖,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼够傍!你這毒婦竟也來(lái)了甫菠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冕屯,失蹤者是張志新(化名)和其女友劉穎寂诱,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體安聘,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痰洒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浴韭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丘喻。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖念颈,靈堂內(nèi)的尸體忽然破棺而出泉粉,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布嗡靡,位于F島的核電站跺撼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏讨彼。R本人自食惡果不足惜歉井,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哈误。 院中可真熱鬧哩至,春花似錦、人聲如沸黑滴。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袁辈。三九已至,卻和暖如春珠漂,著一層夾襖步出監(jiān)牢的瞬間晚缩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工媳危, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荞彼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓待笑,卻偏偏與公主長(zhǎng)得像鸣皂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暮蹂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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

  • 索引 數(shù)據(jù)庫(kù)中的查詢操作非常普遍仰泻,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 2,879評(píng)論 0 8
  • 馬上就要到國(guó)慶節(jié)了集侯,好是期待呀被啼。最近一直忙成狗,急需一個(gè)長(zhǎng)假調(diào)整一下自己的心境和狀態(tài) 今天我們要說(shuō)的是索引相關(guān)的知...
    小煉君閱讀 942評(píng)論 0 50
  • 說(shuō)到索引棠枉,很多人都知道“索引是一個(gè)排序的列表浓体,在這個(gè)列表中存儲(chǔ)著索引的值和包含這個(gè)值的數(shù)據(jù)所在行的物理地址,在數(shù)據(jù)...
    愛(ài)情小傻蛋閱讀 678評(píng)論 2 2
  • 創(chuàng)建高性能索引 索引是什么辈讶?有什么作用命浴? 索引是存儲(chǔ)引擎用于快速找到記錄的一種數(shù)據(jù)結(jié)構(gòu) 如書(shū)的目錄索引一般,數(shù)據(jù)庫(kù)...
    esrever閱讀 651評(píng)論 0 0
  • 適合人群:產(chǎn)品經(jīng)理小白荞估,想跨入產(chǎn)品經(jīng)理行業(yè)的人咳促。 本書(shū)簡(jiǎn)介:作者胡澈稚新,是騰訊產(chǎn)品經(jīng)理。全書(shū)分為五部分跪腹,分別為:什么...
    Lady韓小茹閱讀 505評(píng)論 1 4