欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL中的聚簇索引、非聚簇索引、聯(lián)合索引和唯一索引詳細(xì)介紹

 更新時(shí)間:2023年04月19日 11:55:33   作者:wx: fulltilt8  
本文主要介紹了MySQL的索引類(lèi)型,根據(jù)索引的存儲(chǔ)方式來(lái)劃分,索引可以分為聚簇索引和非聚簇索引。聚簇索引的特點(diǎn)是葉子節(jié)點(diǎn)包含了完整的記錄行,而非聚簇索引的葉子節(jié)點(diǎn)只有所以字段和主鍵ID,感興趣的同學(xué)可以閱讀本文

一、索引類(lèi)型

索引根據(jù)底層實(shí)現(xiàn)可分為B-Tree索引和哈希索引,大部分時(shí)候我們使用的都是B-Tree索引,因?yàn)樗己玫男阅芎吞匦愿m合于構(gòu)建高并發(fā)系統(tǒng)。

根據(jù)索引的存儲(chǔ)方式來(lái)劃分,索引可以分為聚簇索引和非聚簇索引。聚簇索引的特點(diǎn)是葉子節(jié)點(diǎn)包含了完整的記錄行,而非聚簇索引的葉子節(jié)點(diǎn)只有所以字段和主鍵ID。

根據(jù)聚簇索引和非聚簇索引還能繼續(xù)下分還能分為普通索引、覆蓋索引、唯一索引以及聯(lián)合索引等。

二、聚簇索引和非聚簇索引

聚簇索引也叫聚集索引,它實(shí)際上并不是一種單獨(dú)的索引類(lèi)型,而是一種數(shù)據(jù)存儲(chǔ)方式,聚簇索引的葉子節(jié)點(diǎn)保存了一行記錄的所有列信息。也就是說(shuō),聚簇索引的葉子節(jié)點(diǎn)中,包含了一個(gè)完整的記錄行。

非聚簇索引也叫輔助索引、普通索引,它的葉子節(jié)點(diǎn)只包含一個(gè)主鍵值,通過(guò)非聚簇索引查找記錄要先找到主鍵,然后通過(guò)主鍵再到聚簇索引中找到對(duì)應(yīng)的記錄行,這個(gè)過(guò)程被稱(chēng)為回表。

例如一個(gè)包含了用戶(hù)姓名和年齡的的數(shù)據(jù)表,假設(shè)主鍵是用戶(hù)ID,聚簇索引的結(jié)構(gòu)為(橙色的代表id,綠色是指向子節(jié)點(diǎn)的指針):

葉子節(jié)點(diǎn)中,為了突出記錄,把(id, name, age)區(qū)分開(kāi)來(lái)了,實(shí)際上是連在一起的,它們是構(gòu)成一條記錄的整體。

而一個(gè)非聚簇索引(以age為索引)的結(jié)構(gòu)是:

它的葉子節(jié)點(diǎn)中,不包含整個(gè)記錄的完整信息,除了age字段本身以外,只包含當(dāng)前記錄的主鍵id。如果想要獲取整行記錄數(shù)據(jù)還需要再通過(guò)id號(hào)到聚簇索引中回表查詢(xún)。

InnoDB中,每個(gè)表必須有一個(gè)聚簇索引,默認(rèn)是根據(jù)主鍵建立的。如果表中沒(méi)有主鍵,InnoDB會(huì)選擇一個(gè)合適的列作為聚簇索引,如果找不到合適的列,會(huì)使用一列隱藏的列DB_ROW_ID作為聚簇索引。

三、覆蓋索引

非聚簇索引中因?yàn)椴缓型暾臄?shù)據(jù)信息,查找完整的數(shù)據(jù)記錄需要回表,所以一次查詢(xún)操作實(shí)際上要做兩次索引查詢(xún)。而如果所有的索引查詢(xún)都要經(jīng)過(guò)兩次才能查到,那么肯定會(huì)引起效率下降,畢竟能少查一次就少查一次。

以上面的age索引為例,它是一個(gè)非聚簇索引,如果我想通過(guò)年齡查詢(xún)用戶(hù)的id,執(zhí)行了下面一條語(yǔ)句:

1

select id from userinfo where age = 10;

這種情況是否還有必要去回表?因?yàn)槲抑恍枰猧d的值,通過(guò)age這個(gè)索引就已經(jīng)能拿到id了,如果還去回表一次不就做了無(wú)用的操作了嗎?實(shí)際上確實(shí)是不需要的。索引查詢(xún)中,如果輔助索引已經(jīng)能夠得到查詢(xún)的所有信息了,就無(wú)需再回表,這個(gè)就是覆蓋索引。

四、聯(lián)合索引

聯(lián)合索引指的是同時(shí)對(duì)多列創(chuàng)建的索引,創(chuàng)建聯(lián)合索引后,葉子節(jié)點(diǎn)會(huì)同時(shí)包含每個(gè)索引列的值,并且同時(shí)根據(jù)多列排序,這個(gè)排序和我們所理解的字典序類(lèi)似。

例如對(duì)同時(shí)對(duì)上面的姓名和年齡創(chuàng)建的索引結(jié)構(gòu):

(name, age)都是簡(jiǎn)寫(xiě),想不出十幾個(gè)名字。。。。。

每個(gè)葉子節(jié)點(diǎn)同時(shí)保存了所有的索引列,除此之外,還是只包含了主鍵id。

最左前綴匹配原則

當(dāng)對(duì)多列創(chuàng)建索引后,并不是只要包含了創(chuàng)建索引的列就能使用索引,索引的使用要遵循最左前綴匹配原則。

假設(shè)對(duì)列(A, B, C)創(chuàng)建索引,那么只有以下場(chǎng)景能使用索引:

  • 對(duì)列(A, B, C)/(A, C)或者(A, B)進(jìn)行查詢(xún)會(huì)匹配索引,對(duì)(C, A)或者(B, C)來(lái)說(shuō)不能使用索引。
  • 通配符只能使用LIKE 'val%'形式,不能使用LIKE '%VAL%',后者會(huì)導(dǎo)致全表掃描。
  • 索引列不能進(jìn)行運(yùn)算,例如WHERE A + 1 = 5這種場(chǎng)景會(huì)導(dǎo)致索引失效。
  • 索引列不能包含范圍值查詢(xún),如LIKE/BETWEEN/>/<等都會(huì)導(dǎo)致后面的列無(wú)法匹配索引。
  • 索引列不能包含有NULL值。

索引下推

新版本的MySQL(5.6以上)中引入了索引下推的機(jī)制:可以在索引遍歷過(guò)程中,對(duì)索引中包含的字段先做判斷,直接過(guò)濾掉不滿(mǎn)足條件的記錄,減少回表次數(shù)。

例如針對(duì)上面表中的(name, age)做聯(lián)合索引,正常情況下的查詢(xún)邏輯:

  • 通過(guò)name找到對(duì)應(yīng)的主鍵ID
  • 根據(jù)id記錄的列匹配age條件

這種做法會(huì)導(dǎo)致很多不必要的回表,例如表中存在(張三, 10)和(張三, 15)兩條記錄,此刻要查詢(xún)(張三, 20)的記錄。查詢(xún)時(shí)先通過(guò)張三定位到所有符合條件的主鍵ID,然后在聚簇索引中遍歷滿(mǎn)足條件的行,看是否有符合age = 20的記錄。實(shí)際情況是沒(méi)有滿(mǎn)足條件的記錄的,這個(gè)回表過(guò)程也相當(dāng)于是在做無(wú)用之功。

索引下推的主要功能就是改善這一點(diǎn),在聯(lián)合索引中,先通過(guò)姓名和年齡過(guò)濾掉不用回表的記錄,然后再回表查詢(xún)索引,減少回表次數(shù)。

五、唯一索引

唯一索引是一種不允許具有相同索引值的索引,系統(tǒng)在創(chuàng)建該索引時(shí)檢查是否有重復(fù)的鍵值,每次對(duì)更新或增加記錄時(shí)都會(huì)檢查這一點(diǎn)。主鍵索引就是唯一索引。

到此這篇關(guān)于MySQL中的聚簇索引、非聚簇索引、聯(lián)合索引和唯一索引詳細(xì)介紹的文章就介紹到這了,更多相關(guān)MySQL索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論