B+ 樹索引
全文索引
哈希索引
B+ 樹索引就是傳統意義上的索引,這是目前關係型數據庫系統中查找最爲常用和最爲有效的索引。
B+ 樹索引可以分成聚集索引和輔助索引,這兩個索引不同的是葉子節點存放的是否是一整行的信息。
聚集索引就是按照每張表的主鍵構造一課 B+ 樹,同時葉子節點中存放的即爲整張表的行記錄數據,也將聚集索引的葉子節點稱爲數據頁。每個數據頁都通過一個雙向鏈表來進行鏈接。
輔助索引 葉子節點並不包含行記錄的全部數據。葉子節點除了包含鍵值以爲,每個葉子節點中的索引行還包含了一個書籤(bookmark)。該書籤用來告訴 InnoDB 存儲引擎哪裏可以找到與索引想對應的行數據。
當通過輔助索引來尋找數據時,InnoDB 存儲引擎會遍歷輔助索引並通過葉級別的指針獲得指向主鍵索引的主鍵,然後再通過主鍵索引來找到一個完整的行記錄。 如果在一個高度爲 3 的輔助索引樹中查找數據,那需要對這棵輔助索引樹遍歷 3 次找到指定主鍵,如果聚集索引樹的高度同樣爲 3,那麼還需要對聚集索引樹進行 3 次查找,最終找到一個完整的行數據所在的頁,因此一共需要 6 次邏輯 IO 訪問最終的一個數據頁。
聯合索引
CREATE TABLE t (
a INT,
b INT,
PRIMARY KEY (a),
KEY idx_a_b (a ,b)
)ENGINE=INNODB
鍵值都是排序的。聯合索引會對對後面幾個鍵值也進行排序
CREATE TABLE buy_log(
userid INT UNSIGNED NOT NULL,
age INT,
username VARCHAR(100),
buy_date DATE
)ENGINE=INNODB;
//插入
INSERT INTO buy_log VALUES (3,21,'ccc','2018-09-05');
INSERT INTO buy_log VALUES (4,23,'ddd','2018-09-05');
INSERT INTO buy_log VALUES (2,21,'bbb','2018-09-05');
INSERT INTO buy_log VALUES (1,22,'aaa','2018-09-05');
INSERT INTO buy_log VALUES (3,21,'ccc','2018-08-05');
INSERT INTO buy_log VALUES (1,22,'aaa','2018-06-05');
INSERT INTO buy_log VALUES (4,23,'ddd','2018-01-05');
INSERT INTO buy_log VALUES (5,20,'eee','2018-09-05');
INSERT INTO buy_log VALUES (5,20,'eee','2018-06-05');
//添加索引
ALTER TABLE buy_log ADD KEY (userid);
ALTER TABLE buy_log ADD KEY (userid,age);
ALTER TABLE buy_log ADD KEY (userid,age,buy_date);
EXPLAIN SELECT * FROM buy_log WHERE userid=2 ;
有 3 個索引可以使用,但是優化器最終選擇索引 userid
EXPLAIN SELECT * FROM buy_log WHERE userid=1 AND age=22 ORDER BY buy_date ;
優化器選擇索引 userid_3
EXPLAIN SELECT * FROM buy_log WHERE userid=1 ORDER BY age;
優化器選擇索引 userid_2
EXPLAIN SELECT * FROM buy_log WHERE userid=1 ORDER BY buy_date ;
聯合索引不能直接得到結果還需要執行一次 filesort 排序,因爲(userid,buy_date)並未排序。
覆蓋索引
從輔助索引中就可以得到查詢記錄,而不需要查詢聚集索引中的記錄。使用覆蓋索引的一個好處是輔助索引不包含整行記錄的所有信息,故其大小遠小於聚集索引,因此可以減少大量的 IO 操作。
哈希索引
全文搜索
場景:用戶需要查詢博客內容包含單詞 xxx 的文章
倒排索引
它在輔助表中存儲了單詞與單詞自身在一個或多個文檔只呢個所在位置之間的映射。這通常利用關聯數組實現,其擁有兩種表現形式:
inverted file index,其表現形式爲 {單詞,單詞所在文檔的 ID}
full inverted index,其表現形式爲 {單詞,(單詞所在文檔的 ID,在具體文檔中的位置)}
InnoDB 存儲引擎從 1.2.x 版本開始支持全文搜索的技術,其採用 full inverted index 的方式。
MySQL 通過 MATCH() .. AGAINST() 語法支持全文檢索的查詢,MATCH 指定需要被查詢的列,AGAINST 指定了使用何種方法區進行查詢。
參考
MySQL 技術內幕 InnoDB 存儲引擎