MySQL索引(一)索引基礎

索引是數據庫系統裏面最重要的概念之一。一句話簡單來講,索引的出現實際上是爲了提升數據查詢的效率,就像書的目錄同樣。mysql

常見模型

索引的出現是爲了提升查詢效率,可是實現索引的方式卻有不少種,這裏就介紹三種常見、也比較簡單的數據結構,它們分別是哈希表、有序數組和搜索樹。sql

哈希表

哈希表是一種以key-value存儲數據的結構。經過哈希函數把key換算成一個肯定位置,而後把value放在這個數據的這個位置上。數據庫

可是當存儲的數據愈來愈多,就有可能出現兩個不一樣的key經過哈希函數獲得了同樣的值,這時候就出現衝突。而這時就引入鏈表來解決這種衝突了。數組

哈希表這種數據結構適用於只有等值查詢的場景,時間複雜度爲O(1),可是對於範圍查找就必須所有遍歷了,時間複雜度爲O(n)。數據結構

有序數組

有序數組在等值查詢和範圍查詢場景中的性能很是優秀。函數

可是須要往中間插入時就必需要挪動數據,時間複雜度很高。性能

搜索樹

二叉搜索樹在查詢和插入、刪除數據方面可以中和上面兩種結構。查找時間複雜爲O(logn)、插入刪除的時間複雜度爲O(logn)。設計

雖然二叉搜索樹的搜索效率很高,可是在大多數的數據庫並不使用二叉樹。緣由是索引要寫在磁盤上。指針

磁盤上的隨機讀是很耗時間的,爲了讓一個查詢儘可能少地讀磁盤,就必須在查詢過程當中訪問儘可能少的數據塊。code

那麼就不該該使用二叉樹,而是要使用「N」叉樹,這裏的「N」取決於數據塊的大小。

B+樹是爲磁盤設計的一種平衡查找樹。在B+樹中,全部記錄節點都是按鍵值的大小順序存放在同一層的葉子節點上,由各葉子節點指針進行鏈接。

image

索引類型

B+樹索引

數據庫中的B+樹索引能夠分爲主鍵索引和普通索引兩種,也有叫彙集索引(clustered index)和輔助索引(secondary index)

但不論是主鍵索引仍是普通索引,都是使用B+樹的,即高度平衡的,葉子節點存放着全部數據。

主鍵索引

InnoDB存儲引擎表是索引組織表,即表中數據按主鍵順序存放。

主鍵索引就是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的是行數據。每張表只能擁有一個主鍵索引。

普通索引

普通索引與主鍵索引的區別在於,普通索引的葉子節點並不包含行數據,而是包含主鍵。

主鍵索引和普通索引的B+樹

基於主鍵索引和普通索引的查詢有什麼區別?

  • 若是語句是select * from T where ID=500,即主鍵索引查詢方式,則只須要搜索ID這棵B+樹;
  • 若是語句是select * from T where k=5,即普通索引查詢,則須要先搜索k索引樹,獲得ID的值爲500,再到ID索引樹搜索一次。這個過程稱爲回表。

也就是說,基於非主鍵索引的查詢須要多掃描一棵索引樹。所以咱們應該儘可能使用主鍵索引查詢。

哈希索引

哈希索引基於哈希表實現,在MySQL中只有Memory引擎顯示支持哈希索引,也是Memory引擎表的默認索引類型。

下面是建立Memory引擎表的語句:

CREATE TABLE `testhash` (
  `fname` varchar(50) DEFAULT NULL,
  `lname` varchar(50) DEFAULT NULL,
  KEY `fname` (`fname`) USING HASH
) ENGINE=MEMORY;
哈希索引限制
  1. 哈希索引只保存哈希碼和指針,而不存儲字段值,因此不能使用索引中的值來避免讀取行。不過訪問內存中的行速度很是快,因此對性能影響並不大。
  2. 哈希索引數據並非按照索引值順序存儲的,因此沒法沒法用於排序
  3. 哈希索引不支持部分索引列查找,由於哈希索引始終是使用索引列的所有內容來計算哈希碼。
  4. 哈希索引只支持等值比較查詢,不支持範圍查詢。
  5. 哈希衝突會影響查詢速度,此時須要遍歷索引中的行指針,逐行進行比較。
  6. 若是哈希衝突不少,一些索引維護操做的代價會很高。
自定義哈希索引

在InnoDB中,某些索引值被使用的很是頻繁的時候,它會在內存中基於B+樹的基礎上再建立一個哈希索引,使其沒必要要從根節點就查找。徹底自動的內部行爲,用戶沒法配置或更改。

相關文章
相關標籤/搜索