1. 程式人生 > 實用技巧 >MySQL索引(一)索引基礎

MySQL索引(一)索引基礎

索引是資料庫系統裡面最重要的概念之一。一句話簡單來說,索引的出現其實是為了提高資料查詢的效率,就像書的目錄一樣。

常見模型

索引的出現是為了提高查詢效率,但是實現索引的方式卻有很多種,這裡就介紹三種常見、也比較簡單的資料結構,它們分別是雜湊表、有序陣列和搜尋樹。

雜湊表

雜湊表是一種以key-value儲存資料的結構。通過雜湊函式把key換算成一個確定位置,然後把value放在這個資料的這個位置上。

但是當儲存的資料越來越多,就有可能出現兩個不同的key通過雜湊函式得到了一樣的值,這時候就出現衝突。而這時就引入連結串列來解決這種衝突了。

雜湊表這種資料結構適用於只有等值查詢的場景,時間複雜度為O(1),但是對於範圍查詢就必須全部遍歷了,時間複雜度為O(n)。

有序陣列

有序陣列在等值查詢和範圍查詢場景中的效能非常優秀。

但是需要往中間插入時就必須要挪動資料,時間複雜度很高。

搜尋樹

二叉搜尋樹在查詢和插入、刪除資料方面能夠中和上面兩種結構。查詢時間複雜為O(logn)、插入刪除的時間複雜度為O(logn)。

雖然二叉搜尋樹的搜尋效率很高,但是在大多數的資料庫並不使用二叉樹。原因是索引要寫在磁碟上。

磁碟上的隨機讀是很耗時間的,為了讓一個查詢儘量少地讀磁碟,就必須在查詢過程中訪問儘量少的資料塊。

那麼就不應該使用二叉樹,而是要使用“N”叉樹,這裡的“N”取決於資料塊的大小。

B+樹是為磁碟設計的一種平衡查詢樹。在B+樹中,所有記錄節點都是按鍵值的大小順序存放在同一層的葉子節點上,由各葉子節點指標進行連線。

索引型別

B+樹索引

資料庫中的B+樹索引可以分為主鍵索引和普通索引兩種,也有叫聚集索引(clustered index)和輔助索引(secondary index)

但不管是主鍵索引還是普通索引,都是使用B+樹的,即高度平衡的,葉子節點存放著所有資料。

主鍵索引

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

主鍵索引就是按照每張表的主鍵構造一棵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+樹的基礎上再建立一個雜湊索引,使其不必要從根節點就查詢。完全自動的內部行為,使用者無法配置或更改。