索引是物理數據頁存儲,在數據文件中(InnoDB,ibd文件),利用數據頁(page)存儲。 索引能夠加快檢索速度,可是同時也會下降增刪改操做速度,索引維護須要代價。
索引涉及的理論知識:二分查找法、Hash和B+Tree。算法
二分查找法也叫做折半查找法,它是在有序數組中查找指定數據的搜索算法。數據庫
優勢是等值查詢、範圍查詢性能優秀 缺點是更新數據、新增數據、刪除數據維護成本高。
(left+right)/2
public static int binarySearch(int key, int... array) { int low = 0; int high = array.length - 1; while (low <= high) { int mid = low + (high - low) / 2; if (key < array[mid]) { high = mid - 1; } else if (key > array[mid]) { low = mid + 1; } else { return mid; } } return -1; }
Hash底層實現是由Hash表來實現的,是根據鍵值 <key,value> 存儲數據的結構。
很是適合根據key查找value值,也就是單個key查詢,或者說等值查詢。數組
Hash索引能夠方便的提供等值查詢,可是對於範圍查詢就須要全表掃描了。性能
Hash索引在MySQL中Hash結構主要應用在Memory(存儲引擎 基於內存 不多用)原生的Hash索引 、InnoDB 自適應哈希索引。優化
InnoDB自適應哈希索引是爲了提高查詢效率,InnoDB存儲引擎會監控表上各個索引頁的查詢,當InnoDB注意到某些索引值訪問很是頻繁時,會在內存中基於B+Tree索引再建立一個哈希索引,使得內存中的 B+Tree 索引具有哈希索引的功能,即可以快速定值訪問頻繁訪問的索引頁。spa
InnoDB自適應哈希索引:在使用Hash索引訪問時,一次性查找就能定位數據,等值查詢效率要優於B+Tree。指針
自適應哈希索引的創建使得InnoDB存儲引擎能自動根據索引頁訪問的頻率和模式自動地爲某些熱點頁創建哈希索引來加速訪問。
另外InnoDB自適應哈希索引的功能,用戶只能選擇開啓或關閉功能,沒法進行人工干涉。code
show engine innodb status \G; show variables like '%innodb_adaptive%';
MySQL數據庫索引採用的是B+Tree結構,在B-Tree結構上作了優化改造blog
B-Tree結構索引
B樹的搜索:從根節點開始,對節點內的索引值序列採用二分法查找,若是命中就結束查找。沒有命中會進入子節點重複查找過程,直到所對應的的節點指針爲空,或已是葉子節點了才結束。
B+Tree結構
相比B樹,B+樹進行範圍查找時,只須要查找定位兩個節點的索引值,而後利用葉子節點的指針進行遍歷便可。而B樹須要遍歷範圍內全部的節點和數據,顯然B+Tree效率高。
聚簇索引和非聚簇索引:B+Tree的葉子節點存放主鍵索引值和行記錄就屬於聚簇索引;若是索引值和行記錄分開存放就屬於非聚簇索引。
主鍵索引和輔助索引:B+Tree的葉子節點存放的是主鍵字段值就屬於主鍵索引;若是存放的是非主鍵值就屬於輔助索引(二級索引)。
在InnoDB引擎中,主鍵索引採用的就是聚簇索引結構存儲。
聚簇索引(彙集索引)
聚簇索引是一種數據存儲方式,InnoDB的聚簇索引就是按照主鍵順序構建 B+Tree結構。B+Tree的葉子節點就是行記錄,行記錄和主鍵值緊湊地存儲在一塊兒。 這也意味着 InnoDB 的主鍵索引就是數據表自己,它按主鍵順序存放了整張表的數據,佔用的空間就是整個表數據量的大小。一般說的主鍵索引就是彙集索引。
輔助索引
InnoDB輔助索引,也叫做二級索引,是根據索引列構建 B+Tree結構。但在 B+Tree 的葉子節點中只存了索引列和主鍵的信息。二級索引佔用的空間會比聚簇索引小不少, 一般建立輔助索引就是爲了提高查詢效率。一個表InnoDB只能建立一個聚簇索引,但能夠建立多個輔助索引。
非聚簇索引
與InnoDB表存儲不一樣,MyISAM數據表的索引文件和數據文件是分開的,被稱爲非聚簇索引結構。