首頁 > mysql教程 閱讀:0更新時間:2020-03-28 04:08:33

MySQL索引簡介

索引是 mysql 數據庫中的重要對象之一,用于快速找出某個列中有某一特定值的行。

為什么要使用索引

索引是 MySQL 中一種十分重要的數據庫對象。它是數據庫性能調優技術的基礎,常用于實現數據的快速檢索。

索引就是根據表中的一列或若干列按照一定順序建立的列值與記錄行之間的對應關系表,實質上是一張描述索引列的列值與原表中記錄行之間一一對應關系的有序表。

在 MySQL 中,通常有以下兩種方式訪問數據庫表的行數據:

1) 順序訪問

順序訪問是在表中實行全表掃描,從頭到尾逐行遍歷,直到在無序的行數據中找到符合條件的目標數據。這種方式實現比較簡單,但是當表中有大量數據的時候,效率非常低下。例如,在幾千萬條數據中查找少量的數據時,使用順序訪問方式將會遍歷所有的數據,花費大量的時間,顯然會影響數據庫的處理性能。

2) 索引訪問

索引訪問是通過遍歷索引來直接訪問表中記錄行的方式。使用這種方式的前提是對表建立一個索引,在列上創建了索引之后,查找數據時可以直接根據該列上的索引找到對應記錄行的位置,從而快捷地查找到數據。索引存儲了指定列數據值的指針,根據指定的排序順序對這些指針排序。

例如,在學生基本信息表 students 中,如果基于 student_id 建立了索引,系統就建立了一張索引列到實際記錄的映射表,當用戶需要查找 student_id 為 12022 的數據的時候,系統先在 student_id 索引上找到該記錄,然后通過映射表直接找到數據行,并且返回該行數據。因為掃描索引的速度一般遠遠大于掃描實際數據行的速度,所以采用索引的方式可以大大提高數據庫的工作效率。

索引的分類

索引的類型和存儲引擎有關,每種存儲引擎所支持的索引類型不一定完全相同。根據存儲方式的不同,MySQL 中常用的索引在物理上分為以下兩類。

1) B-樹索引

B-樹索引又稱為 BTREE 索引,目前大部分的索引都是采用 B-樹索引來存儲的。B-樹索引是一個典型的數據結構,其包含的組件主要有以下幾個:
  • 葉子節點:包含的條目直接指向表里的數據行。葉子節點之間彼此相連,一個葉子節點有一個指向下一個葉子節點的指針。
  • 分支節點:包含的條目指向索引里其他的分支節點或者葉子節點。
  • 根節點:一個 B-樹索引只有一個根節點,實際上就是位于樹的最頂端的分支節點。

基于這種樹形數據結構,表中的每一行都會在索引上有一個對應值。因此,在表中進行數據查詢時,可以根據索引值一步一步定位到數據所在的行。

B-樹索引可以進行全鍵值、鍵值范圍和鍵值前綴查詢,也可以對查詢結果進行 ORDER BY 排序。但 B-樹索引必須遵循左邊前綴原則,要考慮以下幾點約束:
  • 查詢必須從索引的最左邊的列開始。
  • 查詢不能跳過某一索引列,必須按照從左到右的順序進行匹配。
  • 存儲引擎不能使用索引中范圍條件右邊的列。

2) 哈希索引

哈希(Hash)一般翻譯為“散列”,也有直接音譯成“哈希”的,就是把任意長度的輸入(又叫作預映射,pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。

哈希索引也稱為散列索引或 HASH 索引。MySQL 目前僅有 MEMORY 存儲引擎和 HEAP 存儲引擎支持這類索引。其中,MEMORY 存儲引擎可以支持 B- 樹索引和 HASH 索引,且將 HASH 當成默認索引。

HASH 索引不是基于樹形的數據結構查找數據,而是根據索引列對應的哈希值的方法獲取表的記錄行。哈希索引的最大特點是訪問速度快,但也存在下面的一些缺點:
  • MySQL 需要讀取表中索引列的值來參與散列計算,散列計算是一個比較耗時的操作。也就是說,相對于 B- 樹索引來說,建立哈希索引會耗費更多的時間。
  • 不能使用 HASH 索引排序。
  • HASH 索引只支持等值比較,如“=”“IN()”或“<=>”。
  • HASH 索引不支持鍵的部分匹配,因為在計算 HASH 值的時候是通過整個索引值來計算的。

根據索引的具體用途,MySQL 中的索引在邏輯上分為以下 5 類:

1) 普通索引

普通索引是最基本的索引類型,唯一任務是加快對數據的訪問速度,沒有任何限制。創建普通索引時,通常使用的關鍵字是 INDEX 或 KEY。

2) 唯一性索引

唯一性索引是不允許索引列具有相同索引值的索引。如果能確定某個數據列只包含彼此各不相同的值,在為這個數據列創建索引的時候就應該用關鍵字 UNIQUE 把它定義為一個唯一性索引。

創建唯一性索引的目的往往不是為了提高訪問速度,而是為了避免數據出現重復。

3) 主鍵索引

主鍵索引是一種唯一性索引,即不允許值重復或者值為空,并且每個表只能有一個主鍵。主鍵可以在創建表的時候指定,也可以通過修改表的方式添加,必須指定關鍵字 PRIMARY KEY。

注意:主鍵是數據庫考察的重點。注意每個表只能有一個主鍵。

4) 空間索引

空間索引主要用于地理空間數據類型 GEOMETRY。

5) 全文索引

全文索引只能在 VARCHAR 或 TEXT 類型的列上創建,并且只能在 MyISAM 表中創建。

索引在邏輯上分為以上 5 類,但在實際使用中,索引通常被創建成單列索引和組合索引。
  • 單列索引就是索引只包含原表的一個列。
  • 組合索引也稱為復合索引或多列索引,相對于單列索引來說,組合索引是將原表的多個列共同組成一個索引。

提示:一個表可以有多個單列索引,但這些索引不是組合索引。一個組合索引實質上為表的查詢提供了多個索引,以此來加快查詢速度。比如,在一個表中創建了一個組合索引(c1,c2,c3),在實際查詢中,系統用來實際加速的索引有三個:單個索引(c1)、雙列索引(c1,c2)和多列索引(c1,c2,c3)。

為了提高索引的應用性能,MySQL中的索引可以根據具體應用采用不同的索引策略。這些索引策略所對應的索引類型有聚集索引、次要索引、覆蓋索引、復合索引、前綴索引、唯一索引等。

索引的使用原則和注意事項

雖然索引可以加快查詢速度,提高 MySQL 的處理性能,但是過多地使用索引也會造成以下弊端:
  • 創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。
  • 除了數據表占數據空間之外,每一個索引還要占一定的物理空間。如果要建立聚簇索引,那么需要的空間就會更大。
  • 當對表中的數據進行增加、刪除和修改的時候,索引也要動態地維護,這樣就降低了數據的維護速度。

注意:索引可以在一些情況下加速查詢,但是在某些情況下,會降低效率。

索引只是提高效率的一個因素,因此在建立索引的時候應該遵循以下原則:
  • 在經常需要搜索的列上建立索引,可以加快搜索的速度。
  • 在作為主鍵的列上創建索引,強制該列的唯一性,并組織表中數據的排列結構。
  • 在經常使用表連接的列上創建索引,這些列主要是一些外鍵,可以加快表連接的速度。
  • 在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,所以其指定的范圍是連續的。
  • 在經常需要排序的列上創建索引,因為索引已經排序,所以查詢時可以利用索引的排序,加快排序查詢。
  • 在經常使用 WHERE 子句的列上創建索引,加快條件的判斷速度。

與此對應,在某些應用場合下建立索引不能提高 MySQL 的工作效率,甚至在一定程度上還帶來負面效應,降低了數據庫的工作效率,一般來說不適合創建索引的環境如下:
  • 對于那些在查詢中很少使用或參考的列不應該創建索引。因為這些列很少使用到,所以有索引或者無索引并不能提高查詢速度。相反,由于增加了索引,反而降低了系統的維護速度,并增大了空間要求。
  • 對于那些只有很少數據值的列也不應該創建索引。因為這些列的取值很少,例如人事表的性別列。查詢結果集的數據行占了表中數據行的很大比例,增加索引并不能明顯加快檢索速度。
  • 對于那些定義為 TEXT、IMAGE 和 BIT 數據類型的列不應該創建索引。因為這些列的數據量要么相當大,要么取值很少。
  • 當修改性能遠遠大于檢索性能時,不應該創建索引。因為修改性能和檢索性能是互相矛盾的。當創建索引時,會提高檢索性能,降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大于檢索性能時,不應該創建索引。

beylze編程學院,一個分享編程知識和seo優化知識的網站。跟著beylze一起學習,每天都有進步。

通俗易懂,深入淺出,一篇文章只講一個知識點。

文章不深奧,不需要鉆研,在公交、在地鐵、在廁所都可以閱讀,隨時隨地漲姿勢。

文章不涉及代碼,不燒腦細胞,人人都可以學習。

當你決定關注beylze(公眾號:beylze),你已然超越了90%的其他從業者!

相關文章

国产亚洲欧美日韩