MySQL 索引 :哈希索引、B+树索引、最左前缀匹配规则、全文索引
文章目錄
- 索引
- 什么是索引
- 索引優缺點與適用場景
- 常見的索引
- 哈希索引
- 自適應哈希索引
- B+樹索引
- 聚集索引
- 非聚集索引
- 使用方法
- 聯合索引
- 最左前綴匹配規則
- 覆蓋索引
- 全文索引
- 使用方法
索引
什么是索引
在數據庫中,表、數據、索引之間的關系就類似于書籍、書籍內容、書籍目錄。
倘若不使用索引,則MySQL必須遍歷整個表,直到找到數據,而表越大,查詢的時間則越長,則數據庫的效率也就越低。而索引就類似于書籍的目錄,可以幫助我們快速的定位、檢索到需要的數據行,對提高數據庫的性能有著很大的幫助。
在MySQL中,索引是一種特殊的文件,其中包含著對數據表里所有記錄的引用指針。各類索引有各自的數據結構實現。
索引優缺點與適用場景
優點
缺點
考慮到它的優缺點,通常在滿足以下兩種條件的情況下才會為其建立索引
- 數據量較大,并且經常對這些列進行查詢
- 該數據庫表的插入操作,以及對這些列的修改操作頻率較低
常見的索引
因為MySQL 中索引是在存儲引擎層實現的,所以并沒有統一的索引標準,即不同存儲引擎的索引的工作方式并不一樣。而即使多個存儲引擎支持同一種類型的索引,其底層的實現也可能不同。由于 InnoDB 存儲引擎在 MySQL 數據庫中使用最為廣泛,所以下面的討論主要以InnoDB 為例。
在InnoDB存儲引擎中,主要支持以下三種常見的索引, 下面一一對其進行介紹
- B+樹索引
- 哈希索引
- 全文索引
哈希索引
高級數據結構與算法 | 哈希 :哈希沖突、負載因子、哈希函數、哈希表、哈希桶
如果對于哈希不了解的可以查看我之前的一篇博客。
哈希索引的原理其實就是通過除留余數法將鍵值轉換為哈希值,并將數據存儲對應的槽中,如果出現了哈希沖突,則使用鏈地址法進行解決,將數據插入對應槽中的鏈表。
由于哈希是直接通過哈希值來將數據映射到對應位置,所以哈希索引對于等值查詢的效率特別高,但是也正因為這個特性,使得哈希查找在面對范圍查找的時候就毫無用武之地了。
自適應哈希索引
在InnoDB存儲引擎會監控對表上各個索引頁的查詢,如果它觀察到建立哈希索引可以帶來速度提升,則會自行建立哈希索引,這也就是自適應哈希索引。即會自動根據訪問頻率和模式來為熱點數據建立哈希索引。
由于哈希索引是數據庫自身自動創建并使用的,人工無法對其進行干預
B+樹索引
高級數據結構與算法 | B樹、B+樹、B*樹
B+樹這一數據結構在這里就也不詳細講了,如果不了解的可以查看我之前的一篇博客。
比起哈希索引,B+樹索引的優勢主要在于排序查找以及區間查找
在數據庫中,B+樹索引可以分為聚集索引(主鍵索引)和非聚集索引(輔助索引),它們之間的區別在于葉子節點中存放的是否是一整行的信息(即用戶數據)
ps(葉子節點那一層存儲的是頁,而具體的某一個葉子節點才是存儲行)
聚集索引
聚集索引其實就是索引和數據在同一個數據結構中
由于InnoDB存儲引擎中表的數據按照主鍵順序存放,所以聚集索引也就是按照每張表的主鍵來構造出一顆B+樹。由于數據真正的排序方式只能有一種,所以在每張表中只能存在著一個聚集索引。
這顆B+樹的非葉子節點存放的是數據的索引,而葉子節點存放的即為整張表的行記錄數據,所以我們通常也將葉子節點稱為數據頁,并且每個葉子節點之間用雙向鏈表進行連接。
聚集索引對于主鍵的排序查找和范圍查找速度非常快,并且由于葉子節點就是數據,所以只需要查找一次就可以得到結果
非聚集索引
對于非聚集索引(輔助索引)來說,葉子節點并不包含行記錄的全部數據,而是包含了主鍵的值
也就是說,我們需要在非聚集索引中查找到主鍵,再通過主鍵在聚集索引中查找到具體的值,也就是需要兩次查找。
這就好比我們在查看書籍后面的專有名詞索引一樣,通過某個關鍵詞查找到其在哪一個章節中,再通過目錄來找到具體的章節位置。所以非聚集索引其實也就是一個二級索引
基于以上特性,由于輔助索引的存在并不會影響數據在聚集索引中的組織,因此每張表中可以有多個輔助索引
使用方法
創建主鍵約束(PRIMARY KEY)、唯一約束(UNIQUE)、外鍵約束(FOREIGN KEY)時,會自動創建對應列的索引。
查看索引
SHOW INDEX FROM 表名創建
CREATE INDEX 索引名 ON 表名(字段名) 或者 ALTER TABLE 表名 ADD {KEY | INDEX} 索引名刪除
DROP INDEX 索引名 ON 表名聯合索引
聯合索引即對表上的多個列進行索引,例如下圖。
聯合索引和普通的B+樹不同的地方在于它具有多個鍵值,雖然鍵值有序,但是是按照從左往右的優先級以此對鍵值的大小進行排序,例如上圖有兩個鍵值,首先會先按照第一個鍵值的大小進行排序,當第一個鍵相同時,再按照第二個鍵的大小進行排序。
因為以上特性,聯合索引具有最左前綴匹配規則,當不滿足規則時則不會使用聯合索引,而是進行全索引掃描。
最左前綴匹配規則
就以上述數據進行舉例,此時以鍵值(a, b)構建聯合索引
全值匹配查詢
SELECT * FROM TABLE WHERE a = xxx AND b = xxx 、 SELECT * FROM TABLE WHERE a = xxx SELECT * FROM TABLE WHERE b = xxx對于以上幾條查詢語句來說,雖然看起來差不多,但是效率卻大相徑庭。
對于前兩句來說,它們是可以使用聯合索引的,因為無論是按照a作為條件,或者是a和b作為條件,都可以利用索引進行搜索,因為前面也說過了,聯合索引的排序是按照從左往右優先的,所以當查找條件中包含a的時候則不會出現問題。
但對于b=xxx則無法適用以上性質,因為在聯合索引中,后面的主鍵只有在前面的主鍵相同時才會具有有序性,而單獨適用它的時候顯然數據是無序的,所以這時只能進行行全索引掃描。
對于范圍查找也是這么一個道理,假設此時聯合索引的主鍵為(a, b, c)
SELECT * FROM TABLE WHERE a > 3 AND b > 3 SELECT * FROM TABLE WHERE a > 3 AND b > 3 AND c > 3 SELECT * FROM TABLE WHERE a > 3 AND c > 3同樣按照上面的規則,前兩種查詢都可以適用聯合索引,因為其遵循了從左至右的匹配原則,而第三條因為跳過了b,此時的數據是無序的,無法適用索引。
覆蓋索引
覆蓋索引即從輔助索引中就可以得到查詢的記錄,而不需要查詢聚集索引中的記錄。使用覆蓋索引的一個好處就是由于輔助索引中不包含整行的所有記錄,所以它的大小要遠遠小于聚集索引,因此可以減少大量的I/O操作。
由于輔助索引中葉子節點存放的數據就是主鍵,所以當我們要查找主鍵,或者通過主鍵來統計數量的時候,就可以使用覆蓋索引來完成。
全文索引
在之前版本中只有InnoDB并不支持全文檢索,而在InnoDB1.2.x版本之后,InnoDB也加入了全文檢索的功能
全文索引即根據部分段落、句、詞從數據庫中查詢除全文的技術,即根據部分查詢詞獲取對應的文檔。
主要依據倒排索引這一數據結構來實現,這一數據結構通常也在搜索引擎中進行使用,在我的之前的一篇博客中也曾介紹過這一數據結構。
項目介紹:搜素引擎
這里就簡要的介紹一下InnoDB中的倒排索引
其擁有兩種表現形式
- inverted file index(倒排文件索引)
表現形式 {單詞, 單詞所在的文檔ID) - full inverted index(全文倒排索引)
表現形式{單詞, (單詞所在文檔ID,在具體文檔的位置)
例如我們存在以下數據
并將其構建成inverted file index(倒排文件索引)的形式
此時我們就建立起了各個單詞與其對應文檔的一個映射關系。
接著建立full inverted index(全文倒排索引)
此時在之前的基礎上,我們不僅確定了單詞所在的文章,還確定了其所在文章中的對應位置,雖然比起inverted file index來說更加復雜,占據的空間也更多,但是卻能更好的定位數據,并且擴充一些其它的搜索特性
使用方法
創建全文索引
CREATE FULLTEXT INDEX 索引名 ON 表名(字段名);查找方法
MATCH(要匹配的列) AGAINST(要查找的內容)1.自然語言查詢(Natural Language)
自然語言查詢即普通的包含關鍵詞的搜索,例如
2.Boolean
這個模式允許使用IN BOOLEAN MODE修飾符來進行全文檢索,當使用該修飾符時,查詢字符串的前后字符都會有特殊含義。例如+和-分別代表了該單詞必須出現或者一定沒出現
這句查詢即匹配包含查詢詞1并且不包含查詢詞2的結果
SELECT * FROM 表名 WHERE MATCH (要匹配的列) AGAINST ('+查詢詞1 -查詢詞2' IN BOOLEAN MODE);該模式所有選項如下
全文查詢的結果依據相關度進行降序排序,相關度計算依據如下
- 查詢詞是否在文檔中出現過
- 查詢詞在文檔中出現的次數
- 查詢詞在索引列中的數量
- 包含查詢詞的文檔數
總結
以上是生活随笔為你收集整理的MySQL 索引 :哈希索引、B+树索引、最左前缀匹配规则、全文索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中进程间传递文件描述符的方法
- 下一篇: linux cmake编译源码,linu