MySQL索引

索引介紹

索引是什么

  • 官方介紹索引是幫助MySQL高效獲取數(shù)據(jù)數(shù)據(jù)結(jié)構(gòu)。更通俗的說或听,數(shù)據(jù)庫索引好比是一本書前面的目錄探孝,能加快數(shù)據(jù)庫的查詢速度
  • 一般來說索引本身也很大誉裆,不可能全部存儲(chǔ)在內(nèi)存中顿颅,因此索引往往是存儲(chǔ)在磁盤上的文件中的(可能存儲(chǔ)在單獨(dú)的索引文件中,也可能和數(shù)據(jù)一起存儲(chǔ)在數(shù)據(jù)文件中)足丢。
  • 我們通常所說的索引粱腻,包括聚集索引、覆蓋索引斩跌、組合索引绍些、前綴索引、唯一索引等耀鸦,沒有特別說明柬批,默認(rèn)都是使用 B+樹 結(jié)構(gòu)組織(多路搜索樹,并不一定是二叉的)的索引袖订。

索引的優(yōu)勢和劣勢

優(yōu)勢:

  • 可以提高數(shù)據(jù)檢索的效率氮帐,降低數(shù)據(jù)庫的IO成本,類似于書的目錄洛姑。 -- 檢索
  • 通過索引列對數(shù)據(jù)進(jìn)行排序上沐,降低數(shù)據(jù)排序的成本,降低了CPU的消耗楞艾。 --排序
    1. 被索引的列會(huì)自動(dòng)進(jìn)行排序参咙,包括【單列索引】和【組合索引】,只是組合索引的排序要復(fù)雜一些产徊。
    2. 如果按照索引列的順序進(jìn)行排序昂勒,對應(yīng)order by語句來說,效率就會(huì)提高很多舟铜。
    3. where索引列在存儲(chǔ)引擎層處理

劣勢:

  • 索引會(huì)占據(jù)磁盤空間
  • 索引雖然會(huì)提高查詢效率,但是會(huì)降低更新表的效率奠衔。比如每次對表進(jìn)行增刪改操作谆刨,MySQL不僅要保存數(shù)據(jù)塘娶,還有保存或者更新對應(yīng)的索引文件。

索引的分類

單列索引

  • 普通索引:MySQL中基本索引類型痊夭,沒有什么限制刁岸,允許在定義索引的列中插入重復(fù)值和空值,純粹為了查詢數(shù)據(jù)更快一點(diǎn)她我。 add index
  • 唯一索引:索引列中的值必須是唯一的虹曙,但是允許為空值。add unique index
  • 主鍵索引:是一種特殊的唯一索引番舆,不允許有空值酝碳。 pk

組合索引

  • 在表中的多個(gè)字段組合上創(chuàng)建的索引 add index(col1,col2...)
  • 組合索引的使用,需要遵循最左前綴原則(最左匹配原則恨狈,后面高級篇講解)疏哗。
  • 一般情況下,建議使用組合索引代替單列索引(主鍵索引除外禾怠,具體原因后面知識點(diǎn)講解)返奉。

全文索引

  • 只有在MyISAM引擎、InnoDB(5.6以后)上才能使用吗氏,而且只能在CHAR芽偏、VARCHAR、TEXT類型字段上使用全文索引弦讽。 參看 MySQL全文索引
  • 優(yōu)先級最高哮针,先執(zhí)行,不會(huì)執(zhí)行其他索引

索引的使用

創(chuàng)建索引

  • 單列索引之普通索引
CREATE INDEX index_name ON table(column(length)) ; 
alter table table_name ADD INDEX index_name (column(length)) ;
  • 單列索引之唯一索引
CREATE UNIQUE INDEX index_name ON table(column(length)) ; 
alter table table_name add unique index index_name(column);
  • 單列索引之全文索引
CREATE FULLTEXT INDEX index_name ON table(column(length)) ; 
alter table table_name add fulltext index_name(column)
  • 組合索引
ALTER TABLE article ADD INDEX index_titme_time (title(50), time(10)) ;

刪除索引

DROP INDEX index_name ON table;

查看索引

SHOW INDEX FROM table_name;

索引原理分析

索引的存儲(chǔ)結(jié)構(gòu)

索引存儲(chǔ)結(jié)構(gòu)

  • 索引是在存儲(chǔ)引擎中實(shí)現(xiàn)的坦袍,也就是說不同的存儲(chǔ)引擎十厢,會(huì)使用不同的索引;
  • MyISAM和InnoDB存儲(chǔ)引擎:只支持 B+TREE 索引捂齐,也就是說默認(rèn)使用BTREE蛮放,不能夠更換;
  • MEMORY/HEAP存儲(chǔ)引擎:支持HASH和BTREE索引奠宜;

B樹和B+樹

B樹圖示

B樹是為了磁盤或其它存儲(chǔ)設(shè)備而設(shè)計(jì)的一種多叉(下面你會(huì)看到包颁,相對于二叉,B樹每個(gè)內(nèi)結(jié)點(diǎn)有多個(gè)分支压真,即多叉)平衡查找樹娩嚼。多叉平衡

B樹圖示
  • B樹的高度一般都是在2-4這個(gè)高度,樹的高度直接影響IO讀寫的次數(shù)滴肿。
  • 如果是三層樹結(jié)構(gòu)---支撐的數(shù)據(jù)可以達(dá)到20G岳悟,如果是四層樹結(jié)構(gòu)---支撐的數(shù)據(jù)可以達(dá)到幾十T。
B樹和B+樹的區(qū)別

B樹B+樹 的最大區(qū)別在于非葉子節(jié)點(diǎn)是否存儲(chǔ)數(shù)據(jù)的問題。

  • B樹是非葉子節(jié)點(diǎn)和葉子節(jié)點(diǎn)都會(huì)存儲(chǔ)數(shù)據(jù)贵少。
  • B+樹只有葉子節(jié)點(diǎn)才會(huì)存儲(chǔ)數(shù)據(jù)呵俏,而且存儲(chǔ)的數(shù)據(jù)都是在一行上,而且這些數(shù)據(jù)都是有指針指向的滔灶,也就是有順序的普碎。索引列 order by

非聚集索引(MyISAM)

  • B+樹葉子節(jié)點(diǎn)只會(huì)存儲(chǔ)數(shù)據(jù)行(數(shù)據(jù)文件)的指針,簡單來說數(shù)據(jù)和索引不在一起录平,就是非聚集索引麻车。
  • 非聚集索引包含主鍵索引和輔助索引都會(huì)存儲(chǔ)指針的值
主鍵索引
MyISAM主鍵索引圖示

這里假設(shè)表一共有三列,假設(shè)我們以 Col1 為主鍵斗这,則上圖是一個(gè) MyISAM 表的主索引(Primary key)示意动猬。可以看出MyISAM 的索引文件僅僅保存數(shù)據(jù)記錄的地址涝影。

輔助索引(次要索引)

在 MyISAM 中枣察,主鍵索引和輔助索引(Secondary key)在結(jié)構(gòu)上沒有任何區(qū)別,只是主鍵索引要求 key 是唯一的燃逻,而輔助索引的 key 可以重復(fù)序目。如果我們在 Col2 上建立一個(gè)輔助索引,則此索引的結(jié)構(gòu)如下圖所示

MyISAM輔助索引圖示

同樣也是一顆 B+Tree伯襟,data 域保存數(shù)據(jù)記錄的地址猿涨。因此,MyISAM 中索引檢索的算法為首先按照 B+Tree 搜索算法搜索索引姆怪,如果指定的 Key 存在叛赚,則取出其data 域的值,然后以 data 域的值為地址稽揭,讀取相應(yīng)數(shù)據(jù)記錄俺附。

聚集索引(InnoDB)

  • 主鍵索引(聚集索引)的葉子節(jié)點(diǎn)會(huì)存儲(chǔ)數(shù)據(jù)行,也就是說數(shù)據(jù)和索引是在一起溪掀,這就是聚集索引事镣。
  • 輔助索引只會(huì)存儲(chǔ)主鍵值
  • 如果沒有沒有主鍵揪胃,則使用唯一索引建立聚集索引璃哟;如果沒有唯一索引,MySQL會(huì)按照一定規(guī)則創(chuàng)建聚集索引喊递。
主鍵索引

InnoDB 要求表必須有主鍵(MyISAM 可以沒有)随闪,如果沒有顯式指定,則 MySQL系統(tǒng)會(huì)自動(dòng)選擇一個(gè)可以唯一標(biāo)識數(shù)據(jù)記錄的列作為主鍵骚勘,如果不存在這種列铐伴,則MySQL 自動(dòng)為 InnoDB 表生成一個(gè)隱含字段作為主鍵,類型為長整形。

InnoDB主鍵索引圖示

上圖是 InnoDB 主索引(同時(shí)也是數(shù)據(jù)文件)的示意圖盛杰,可以看到葉節(jié)點(diǎn)包含了完整的數(shù)據(jù)記錄挽荡。這種索引叫做聚集索引藐石。因?yàn)?InnoDB 的數(shù)據(jù)文件本身要按主鍵聚集即供。

輔助索引(次要索引)

第二個(gè)與 MyISAM 索引的不同是 InnoDB 的輔助索引 data 域存儲(chǔ)相應(yīng)記錄主鍵的值而不是地址。換句話說于微,InnoDB 的所有輔助索引都引用主鍵作為 data 域逗嫡。如下圖所示,將 Col3 當(dāng)做輔助索引株依,葉子節(jié)點(diǎn)引用主鍵索引驱证,而不是地址值:

iInnoDB輔助索引圖示

聚集索引這種實(shí)現(xiàn)方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:① 首先檢索輔助索引獲得主鍵恋腕;② 然后用主鍵到主索引中檢索獲得記錄抹锄。

select * from user where name = 'Alice';
-- 回表查詢,檢索兩次:非主鍵索引 ---> 主鍵索引 ---> 數(shù)據(jù)

引申:為什么不建議使用過長的字段作為主鍵?
因?yàn)樗休o助索引都引用主索引荠藤,過長的主索引會(huì)令輔助索引變得過大伙单。
同時(shí),請盡量在 InnoDB 上采用自增字段做表的主鍵哈肖。

MyISAM和InnoDB的存儲(chǔ)結(jié)構(gòu)圖示

為了更形象說明這兩種索引的區(qū)別吻育,我們假想一個(gè)表如下圖存儲(chǔ)了 4 行數(shù)據(jù)。 其中 ID 作為主索引淤井,Name 作為輔助索引布疼。 圖示清晰的顯示了聚集索引和非聚集索引的差異:

MyISAM和InnoDB的存儲(chǔ)結(jié)構(gòu)圖示
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市币狠,隨后出現(xiàn)的幾起案子游两,更是在濱河造成了極大的恐慌,老刑警劉巖漩绵,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贱案,死亡現(xiàn)場離奇詭異,居然都是意外死亡渐行,警方通過查閱死者的電腦和手機(jī)轰坊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祟印,“玉大人肴沫,你說我怎么就攤上這事≡桃洌” “怎么了颤芬?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我站蝠,道長汰具,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任菱魔,我火速辦了婚禮留荔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澜倦。我一直安慰自己聚蝶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布藻治。 她就那樣靜靜地躺著碘勉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桩卵。 梳的紋絲不亂的頭發(fā)上验靡,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音雏节,去河邊找鬼胜嗓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛矾屯,可吹牛的內(nèi)容都是我干的兼蕊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼件蚕,長吁一口氣:“原來是場噩夢啊……” “哼孙技!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起排作,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牵啦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后妄痪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哈雏,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年衫生,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裳瘪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡罪针,死狀恐怖彭羹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泪酱,我是刑警寧澤派殷,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布还最,位于F島的核電站,受9級特大地震影響毡惜,放射性物質(zhì)發(fā)生泄漏拓轻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一经伙、第九天 我趴在偏房一處隱蔽的房頂上張望扶叉。 院中可真熱鬧,春花似錦橱乱、人聲如沸辜梳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茶宵,卻和暖如春危纫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乌庶。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工种蝶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞒大。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓螃征,卻偏偏與公主長得像,于是被迫代替她去往敵國和親透敌。 傳聞我的和親對象是個(gè)殘疾皇子盯滚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

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

  • 歡迎Java工程師關(guān)注簡書專欄Java架構(gòu)技術(shù)進(jìn)階本專欄收錄各種Java相關(guān)技術(shù),面試題酗电,以及學(xué)習(xí)感悟魄藕,心得! 一...
    Java高級架構(gòu)獅閱讀 493評論 0 1
  • 1 索引介紹 1.1 索引是什么 官方介紹索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)撵术。更通俗的說背率,數(shù)據(jù)庫索...
    MiniSoulBigBang閱讀 432評論 0 0
  • 一寝姿、概要 索引就像一本書的目錄。而當(dāng)用戶通過索引查找數(shù)據(jù)時(shí)划滋,就好比用戶通過目錄查詢某章節(jié)的某個(gè)知識點(diǎn)饵筑。這樣就幫助用...
    唯老閱讀 422評論 0 1
  • 索引是什么? MySQL官方對索引的定義為:索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)古毛;索引是提高查詢速度的最重要...
    leiyulingling閱讀 261評論 0 0
  • 索引是用來快速檢索出具有特定值的記錄翻翩。如果沒有索引都许,數(shù)據(jù)庫就必須從第一條記錄開始進(jìn)行全表掃描,直到找出相關(guān)的行嫂冻。數(shù)...
    咕泡學(xué)院蓉蓉老師閱讀 460評論 0 2