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

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

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

