1. 程式人生 > >深入理解四種資料庫索引型別(- 唯一索引/非唯一索引

深入理解四種資料庫索引型別(- 唯一索引/非唯一索引

  • 唯一索引/非唯一索引
  • 主鍵索引(主索引)
  • 聚集索引/非聚集索引
  • 組合索引

唯一索引/非唯一索引

唯一索引

1.唯一索引是在表上一個或者多個欄位組合建立的索引,這個或者這些欄位的值組合起來在表中不可以重複。

非唯一索引

2.非唯一索引是在表上一個或者多個欄位組合建立的索引,這個或者這些欄位的值組合起來在表中可以重複,不要求唯一。

主鍵索引(主索引)

3.主鍵索引(主索引)是唯一索引的特定型別。表中建立主鍵時自動建立的索引 。一個表只能建立一個主索引。

聚集索引/非聚集索引

4.聚集索引(聚簇索引),表中記錄的物理順序與鍵值的索引順序相同。一個表只能有一個聚集索引。

擴充套件:聚集索引和非聚集索引的區別?分別在什麼情況下使用?

聚集索引和非聚集索引的根本區別是表中記錄的物理順序和索引的排列順序是否一致。

聚集索引的表中記錄的物理順序與索引的排列順序一致

優點是查詢速度快,因為一旦具有第一個索引值的記錄被找到,具有連續索引值的記錄也一定物理的緊跟其後。

缺點是對錶進行修改速度較慢,這是為了保持表中的記錄的物理順序與索引的順序一致,而把記錄插入到資料頁的相應位置,必須在資料頁中進行資料重排,降低了執行速度。在插入新記錄時資料檔案為了維持 B+Tree 的特性而頻繁的分裂調整,十分低效。

建議使用聚集索引的場合為:
A.某列包含了小數目的不同值。
B.排序和範圍查詢。

非聚集索引的記錄的物理順序和索引的順序不一致

其他方面的區別:
1.聚集索引和非聚集索引都採用了 B+樹的結構,但非聚集索引的葉子層並不與實際的資料頁相重疊,而採用葉子層包含一個指向表中的記錄在資料頁中的指標的方式。聚集索引的葉節點就是資料節點,而非聚集索引的葉節點仍然是索引節點。

2.非聚集索引新增記錄時,不會引起資料順序的重組。

看上去聚簇索引的效率明顯要低於非聚簇索引, 因為每次使用輔助索引檢索都要經過兩次 B+樹查詢, 這不是多此一舉嗎? 聚簇索引的優勢在哪?

1.由於行資料和葉子節點儲存在一起, 這樣主鍵和行資料是一起被載入記憶體的, 找到葉子節點就可以立刻將行資料返回了, 如果按照主鍵 Id 來組織資料, 獲得資料更快。

2.輔助索引使用主鍵作為"指標", 而不是使用地址值作為指標的好處是, 減少了當出現行移動或者資料頁分裂時,輔助索引的維護工作, InnoDB 在移動行時無須更新輔助索引中的這個"指標"。 也就是說行的位置會隨著資料庫裡資料的修改而發生變化, 使用聚簇索引就可以保證不管這個主鍵 B+樹的節點如何變化, 輔助索引樹都不受影響。

建議使用非聚集索引的場合為:
a.此列包含了大數目的不同值;
b.頻繁更新的列

5.組合索引(聯合索引)

基於多個欄位而建立的索引就稱為組合索引。

建立索引
create index idx1 on table1(col1,col2,col3)
查詢
select * from table1 where col1= A and col2= B and col3 = C

組合索引查詢的各種場景
組合索引 Index (A, B, C)

下面條件可以用上該組合索引查詢:
 A>5
 A=5 AND B>6
 A=5 AND B=6 AND C=7
 A=5 AND B=6 AND C IN (2, 3)

下面條件將不能用上組合索引查詢:
 B>5 ——查詢條件不包含組合索引首列欄位
 B=6 AND C=7 ——理由同上

下面條件將能用上部分組合索引查詢(重要! ! ! ! ) :
 A>5 AND B=2 ——當範圍查詢使用第一列, 查詢條件僅僅能使
用第一列
 A=5 AND B>6 AND C=2 ——範圍查詢使用第二列, 查詢條件僅僅能使用
前二列
 A=5 AND B IN (2, 3) AND C=2 ——理由同上

組合索引排序的各種場景:

茲有組合索引 Index(A,B)。
 下面條件可以用上組合索引排序:
 ORDER BY A——首列排序
 A=5 ORDER BY B——第一列過濾後第二列排序
 ORDER BY A DESC, B DESC——注意, 此時兩列以相同順序排序
 A>5 ORDER BY A——資料檢索和排序都在第一列

下面條件不能用上組合索引排序:
 ORDER BY B ——排序在索引的第二列
 A>5 ORDER BY B ——範圍查詢在第一列, 排序在第二列
 A IN(1,2) ORDER BY B ——理由同上
 ORDER BY A ASC, B DESC ——注意, 此時兩列以不同順序排序

alter table users add index lname_fname_age(lname,fname,age);

建立了 lname_fname_age 多列索引,相當於建立了(lname)單列索引,
(lname,fname)聯合索引以及(lname,fname,age)聯合索引。

舉例說明:上面給出一個多列索引(username,password,last_login),當
三 列 在 where 中 出 現 的 順 序 如 (username,password,last_login) 、
(username,password)、(username)才能用到索引,如下面幾個順序
(password,last_login) 、 (passwrod) 、 (last_login)--- 這 三 者 不 從
username 開始,(username,last_login)---斷層,少了 password,都無
法利用到索引。因為 B+tree 多列索引儲存的順序是按照索引建立的順序,
檢索索引時按照此順序檢索。