Mysql?InnoDB聚簇索引二級(jí)索引聯(lián)合索引特點(diǎn)
接上一篇內(nèi)容:http://chabaoo.cn/article/249934.htm
一、聚簇索引
其實(shí)之前內(nèi)容中介紹的 B+ 樹(shù)就是聚簇索引。
這種索引不需要我們顯示地使用 INDEX 語(yǔ)句去創(chuàng)建,InnoDB 引擎會(huì)自動(dòng)創(chuàng)建。另外,在 InnoDB 引擎中,聚簇索引就是數(shù)據(jù)的存儲(chǔ)方式。
它有 2 個(gè)特點(diǎn):
特點(diǎn) 1
使用記錄主鍵值的大小進(jìn)行記錄和頁(yè)的排序。
其中又包含了下面 3 個(gè)點(diǎn):
- 頁(yè)(包括葉節(jié)點(diǎn)和內(nèi)節(jié)點(diǎn))內(nèi)的記錄按照主鍵的大小順序排成一個(gè)單向鏈表。頁(yè)內(nèi)記錄劃分為若干組,每個(gè)組中主鍵值最大的記錄在頁(yè)內(nèi)的偏移量被當(dāng)做槽依次存放在頁(yè)目錄中。我們可以通過(guò)二分法快速定位主鍵值等于某個(gè)值的記錄。
- 各存放用戶(hù)記錄的頁(yè)也是根據(jù)頁(yè)中用戶(hù)記錄的主鍵大小順序排成一個(gè)雙向鏈表。
- 各存放目錄項(xiàng)記錄的頁(yè)分為不同層級(jí)。在同一層級(jí)中的頁(yè),也是根據(jù)頁(yè)中目錄項(xiàng)記錄的主鍵大小順序排成一個(gè)雙向鏈表。
特點(diǎn) 2
B+樹(shù)的葉子節(jié)點(diǎn)存儲(chǔ)的是完整的用戶(hù)記錄。
這里完整的用戶(hù)記錄就是指,這個(gè)記錄中存儲(chǔ)了所有的列的值(包括隱藏列)。
二、二級(jí)索引
聚簇索引只能在我們搜索主鍵值時(shí)才能發(fā)揮作用,因?yàn)?B+ 樹(shù)中的數(shù)據(jù)都是按照主鍵進(jìn)行排序。
如果現(xiàn)在我用“別的列”作為搜索條件,怎么辦?
答案:再建一個(gè) B+ 樹(shù),用這個(gè)“別的列”(非主鍵列)的值大小作為排序規(guī)則。
比如之前的內(nèi)容都是以 c1 列為主鍵,現(xiàn)在用 c2 列再來(lái)創(chuàng)建一個(gè) B+ 樹(shù):

看起來(lái)跟之前的聚簇索引沒(méi)啥區(qū)別啊?實(shí)際上還是存在不同的:
- 使用記錄 c2 列的大小進(jìn)行記錄和頁(yè)的排序。細(xì)分的 3 點(diǎn)與上面聚簇索引介紹的一樣,只不過(guò)上面是主鍵,這里是用的 c2 列(非主鍵)。
- B+ 樹(shù)的葉子節(jié)點(diǎn)存儲(chǔ)的不是完整的用戶(hù)記錄,只有c2 列 + 主鍵這2個(gè)列的值。
- 目錄項(xiàng)記錄中不再是主鍵 + 頁(yè)號(hào),變成了c2 列 + 頁(yè)號(hào)。
另外需要注意的是,因?yàn)?c2 列不是主鍵,所以沒(méi)有唯一性約束,可能存在多條滿足搜索條件的數(shù)據(jù)。
現(xiàn)在根據(jù)條件 c2 = 4 來(lái)查找數(shù)據(jù)記錄,過(guò)程如下:
確定第一條符合 c2 = 4 的目錄項(xiàng)所在頁(yè),也就是頁(yè) 42。
到頁(yè) 42 中,進(jìn)一步確定第一條符合條件的記錄所在的用戶(hù)記錄頁(yè)。因?yàn)?2 < 4 <= 4,所以可能存在 頁(yè) 34 或 35 中。
先到頁(yè) 34 中定位第一條滿足 c2 = 4 的用戶(hù)記錄,如果有就不需要再到頁(yè) 35 中繼續(xù)定位了。
在頁(yè) 34 中定位到第一條記錄。因?yàn)檫@條用戶(hù)記錄不完整,所以拿到這條記錄的主鍵,再到聚簇索引中找到完整的用戶(hù)記錄。
上面最后一步,通過(guò)攜帶主鍵信息到聚簇索引中重新定位完整的用戶(hù)記錄的過(guò)程也叫回表。
回表后,再回到這顆新的 B+ 樹(shù),找到剛才那個(gè)第一個(gè)符合條件的記錄,并沿著記錄的單向鏈表向后繼續(xù)搜索其他也滿足 c2 = 4 的記錄,每找到一條就繼續(xù)回表操作,重復(fù)這個(gè)過(guò)程。
這種以非主鍵列的大小為排序規(guī)則而建立 B+ 樹(shù)需要執(zhí)行回表操作才可以定位到完整的用戶(hù)記錄,這種 B+樹(shù)就稱(chēng)為二級(jí)索引或者輔助索引。
為什么要回表?直接把完整用戶(hù)記錄都放葉子節(jié)點(diǎn)不就可以了?
沒(méi)錯(cuò),思路沒(méi)問(wèn)題。但是這樣操作就相當(dāng)于每建立一顆 B+ 樹(shù)都把所有的用戶(hù)記錄復(fù)制一遍,太浪費(fèi)存儲(chǔ)空間。
三、聯(lián)合索引
我們可以同時(shí)為多個(gè)列建立索引,比如 c2 列和 c3 列,以這 2 個(gè)列的大小為排序規(guī)則建立的 B+ 樹(shù)索引就稱(chēng)為聯(lián)合索引,也稱(chēng)為符合索引或多列索引。
這里的按照 c2 和 c3 列大小進(jìn)行排序,需要注意兩點(diǎn):
- 先把各個(gè)記錄和頁(yè)按照 c2 列進(jìn)行排序。
- 在記錄的 c2 列都相同的情況下,再采用 c3 列進(jìn)行排序。
現(xiàn)在,給c2 和 c3 建立聯(lián)合索引,如圖所示:

需要注意的是:
- 每條目錄項(xiàng)記錄都是由 c2、c3、頁(yè)號(hào)這 3 部分組成。各記錄先按照 c2 列的值進(jìn)行排序,如果記錄的 c2 列相同,則按照 c3 列進(jìn)行排序。
- B+ 樹(shù)葉子節(jié)點(diǎn)的用戶(hù)記錄由 c2、c3、和 主鍵c1 列組成。
本質(zhì)上,聯(lián)合索引也是一個(gè)二級(jí)索引,只不過(guò)它的索引列包括 c2、c3 這2個(gè)列。
本文參考書(shū)籍:《mysql是怎樣運(yùn)行的》
以上就是Mysql InnoDB聚簇索引二級(jí)索引聯(lián)合索引特點(diǎn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Mysql InnoDB聚簇二級(jí)聯(lián)合索引的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
修改MySQL數(shù)據(jù)庫(kù)中表和表中字段的編碼方式的方法
這篇文章主要介紹了如何修改MySQL數(shù)據(jù)庫(kù)中表和表中字段的編碼方式,需要的朋友可以參考下2014-05-05
MySQL query_cache_type 參數(shù)與使用詳解
這篇文章主要介紹了MySQL query_cache_type參數(shù)介紹,需要的朋友可以參考下2021-07-07
詳解Mysql5.7自帶的壓力測(cè)試命令mysqlslap及使用語(yǔ)法
mysqlslap是一個(gè)診斷程序,旨在模擬MySQL服務(wù)器的客戶(hù)端負(fù)載并報(bào)告每個(gè)階段的時(shí)間。這篇文章主要介紹了Mysql5.7自帶的壓力測(cè)試命令mysqlslap的相關(guān)知識(shí),需要的朋友可以參考下2019-10-10
MySQL使用show?effective?grants查看權(quán)限官方解讀
這篇文章主要為大家介紹了MySQL使用show?effective?grants查看權(quán)限,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
計(jì)算機(jī)二級(jí)考試MySQL知識(shí)點(diǎn) 常用MYSQL命令
這篇文章主要介紹了計(jì)算機(jī)二級(jí)考試MySQL知識(shí)點(diǎn),詳細(xì)介紹了常用MYSQL命令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
MySQL線程處于Opening tables的問(wèn)題解決方法
在本篇文章里小編給大家分享了關(guān)于MySQL線程處于Opening tables的問(wèn)題解決方法,有興趣的朋友們學(xué)習(xí)下。2019-01-01
Navicat遠(yuǎn)程連接SQL Server并轉(zhuǎn)換成MySQL步驟詳解
最近遇到一個(gè)需求是將SQL Server轉(zhuǎn)換為 MySQL的格式,由于不想在本地安裝 SQL Server,所以決定在遠(yuǎn)程的 Windows 服務(wù)器上安裝,并在本地使用Navicat遠(yuǎn)程連接它,然而在實(shí)現(xiàn)過(guò)程中遇到了諸多問(wèn)題,記錄于此。感興趣的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-01-01
mariadb集群搭建---Galera Cluster+ProxySQL教程
這篇文章主要介紹了mariadb集群搭建---Galera Cluster+ProxySQL教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03

