聚集索引和非聚集索引的區別底層 資料庫 索引相關

2021-10-11 02:00:14 字數 3828 閱讀 9026

在資料庫中,索引的含義與日常意義上的「索引」一詞並無多大區別(想想小時候查字典),它是用於提高資料庫表資料訪問速度的資料庫物件。

總而言之,索引是乙個排序的列表,在這個列表中儲存著索引的值和包含這個值的資料所在行的實體地址,在資料十分龐大的時候,索引可以大大加快查詢的速度,這是因為使用索引後可以不用掃瞄全表來定位某行的資料,而是先通過索引表找到該行資料對應的實體地址然後訪問相應的資料

當然,眾所周知,雖然索引可以提高查詢速度,但是它們也會導致資料庫系統「更新資料」的效能下降,因為大部分資料更新需要同時更新索引。

什麼樣的字段適合建立索引?

1、表的主鍵、外來鍵一般必須有索引

2、資料量超過300的表應該有索引(不知道是什麼依據,難道是經驗之談?)

3、經常與其他表進行連線的表,在連線欄位上應該建立索引

4、經常出現在where子句中的字段,加快判斷速度,特別是大表的字段,應該建立索引

5、經常用於排序的列上

6、經常用在範圍內搜尋的列上建立索引

什麼場景不適合建立索引?

1、對於那些在查詢中很少使用的列

2、對於那些只有取值種類較少的列也不應該增加索引,例如性別

3、對於那些定義為text、image和bit資料型別的列不應該增加索引。

這些列的資料量要麼相當大,要麼取值很少。

4、當修改效能遠遠大於檢索效能時,不應該建立索引。修改效能和檢索效能是互相矛盾的。當增加索引時,會提高檢索效能,但是會降低修改效能。當減少索引時,會提高修改效能,降低檢索效能。因 此,當修改效能遠遠大於檢索效能時,不應該建立索引。

5、不會出現在where條件中的字段不該建立索引

1、從儲存結構上來劃分:

btree索引(b-tree或b+tree索引),hash索引,full-index全文索引

這裡的儲存結構是指索引的組織形式,比如b+tree索引,就是將索引頁當做乙個乙個節點,然後以b+樹的形式組織起來

2、從應用層次來分:

普通索引:即乙個索引只包含單個列,乙個表可以有多個單列索引

唯一索引:索引列的值必須唯一,但允許有空值

復合索引:多列值組成乙個索引,專門用於組合搜尋,其效率大於索引合併

3、根據中資料的物理順序與鍵值的邏輯(索引)順序關係:

聚集索引:並不是一種單獨的索引型別,而是一種資料儲存方式。

非聚集索引:不是聚簇索引,就是非聚簇索引,或者叫輔助索引

聚集索引和非聚集索引的差別,下面會有更加詳細的說明。

一條索引記錄中包含的基本資訊包括:鍵值(即你定義索引時指定的所有欄位的值)+邏輯指標(指向資料頁或者另一索引頁)

通常狀況下,由於索引記錄僅包含索引字段值以及4-9位元組的指標,索引實體比真實的資料行要小許多,索引頁相較資料頁來說要密集許多。乙個索引頁可以儲存數量更多的索引記錄,這意味著在索引中查詢時在i/o上佔很大的優勢,理解這一點有助於從本質上了解使用索引的優勢。

mysql預設儲存引擎innodb支援常見的幾種索引:

其中,對於頻繁訪問的表,innodb會自動的生成雜湊索引,不能認為干預是否在一張表中生成雜湊索引

資料庫的b+樹索引分為聚集索引和輔助索引或者叫非聚集索引。二者不同的地方是葉子節點存放的是否是一整行的資訊。

聚集索引

表資料按照索引的順序來儲存的。

對於聚集索引,葉子結點即儲存了真實的資料行,不再有另外單獨的資料頁。

當定義下來資料的邏輯順序時,聚集索引能夠比較快速的訪問針對範圍值的查詢非聚集索引

非聚集索引

表資料儲存順序與索引順序無關。對於非聚集索引,葉結點包含索引字段值及指向資料頁資料行的邏輯指標,該層緊鄰資料頁,其行數量與資料表行資料量一致。
在一張表上只能建立乙個聚集索引,因為真實資料的物理順序只可能是一種。

5.1、聚集索引

在聚集索引中,葉結點也稱為資料結點資料頁,所有資料行的儲存順序與索引的儲存順序一致。

如上圖,我們在名字欄位上建立聚集索引,當需要在根據此欄位查詢特定的記錄時,資料庫系統會根據特定的系統表查詢的此索引的根,然後根據指標查詢下乙個,直到找到。例如我們要查詢「green」,由於它介於[bennet,karsen],據此我們找到了索引頁1007,在該頁中「green」介於[greane, hunter]間,據此我們找到葉結點1133(也即資料結點),並最終在此頁中找以了目標資料行。

此次查詢的io包括3個索引頁的查詢(其中最後一次實際上是在資料頁中查詢)。這裡的查詢可能是從磁碟讀取(physical read)或是從快取中讀取(logical read),如果此表訪問頻率較高,那麼索引樹中較高層的索引很可能在快取中被找到。所以真正的io可能小於上面的情況。

5.2、非聚集索引

非innodb實現:

非聚集索引與聚集索引相比:

聚集索引是一種稀疏索引,資料頁上一級的索引頁儲存的是頁指標,而不是行指標。

而對於非聚集索引,則是密集索引,在資料頁的上一級索引頁它為每乙個資料行儲存一條索引記錄。

對於根與中間級的索引記錄,它的結構包括:

對於葉子層的索引物件,它的結構包括:

針對上圖,如果我們同樣查詢「green」,那麼一次查詢操作將包含以下io: 3個索引頁的讀取+1個資料頁的讀取。同樣,由於快取的關係,真實的io實際可能要小於上面列出的。

innodb實現:

在innodb中,非聚集索引的葉子節點並不包含行記錄的全部資訊,除了包含鍵值以外,還有包含了乙個書籤bookmark,本質上,bookmark就是相應行資料的「聚集索引鍵」

在進行查詢時,本質上是從非主鍵->主鍵->行記錄的查詢過程

輔助索引的存在並不影的資料在聚集索引中的組織。因此每張表上可以有多個輔助索引。當通過輔助索引來查詢資料時,innodb儲存引擎會遍歷輔助索引並通過葉節點的指標獲得指向主鍵索引的主鍵,然後再通過主鍵索引來找到乙個完整的行記錄。

舉例來說。如果在一一棵高度為3的輔助索引樹中查詢資料,那需要對這個輔助索引樹遍歷3次找到指定的主鍵,如果聚集索引的高度同樣為3,那麼需要對聚集索引進行三次查詢,最終找到乙個記錄所在的頁,因此一共需要進行6次邏輯io才能得到最終的邏輯頁。

innodb使用b+tree作為索引資料結構。

從物理儲存結構上說,b-tree和b+tree都以頁(4k)來劃分節點的大小,但是由於b+tree中中間節點不儲存資料,因此b+tree能夠在同樣大小的節點中,儲存更多的key,提高查詢效率。

影響mysql查詢效能的主要還是磁碟io次數,大部分是磁頭移動到指定磁軌的時間花費。

innodb儲存引擎下索引的實現,(輔助索引)全部是依賴於主索引建立的(輔助索引中葉子結點儲存的並不是資料的位址,還是主索引的值,因此,所有依賴於輔助索引的都是先根據輔助索引查到主索引,再根據主索引查資料的位址)。

漫談資料庫索引

mysql技術內幕 (豆瓣)

mysql索引的新手入門詳解

深入理解mysql索引原理和實現

爪哇滑小稽:面試的時候怎麼和面試官講解你對mysql索引的理解

聚集索引 和 非聚集索引區別

一.mysql的索引 mysql中,不同的儲存引擎對索引的實現方式不同,大致說下myisam和innodb兩種儲存引擎。myisam的b tree的葉子節點上的data,並不是資料本身,而是資料存放的位址。主索引和輔助索引沒啥區別,只是主索引中的key一定得是唯一的。這裡的索引都是非聚簇索引。myi...

聚集索引和非聚集索引區別

聚集索引 資料行的物理順序與列值 一般是主鍵那一列 的邏輯順序相同,乙個表只能擁有乙個聚集索引!非聚集索引 該索引中索引的邏輯順序與磁碟上行的物理順序不同乙個表可以擁有多個非聚集索引!非聚集索引可細分成普通索引,唯一索引,全文索引 區別 聚集索引 可以幫助把很大的範圍,迅速減小範圍。但是查詢該記錄,...

聚集索引和非聚集索引的區別

暫且摘錄如下 摘錄1 前者加在不常更新的表,後者加在經常更新的表 摘錄2 使用聚集索引 聚集索引確定表中資料的物理順序。聚集索引類似於 簿,後者按姓氏排列資料。由於聚集索引規定資料在表中的物理儲存順序,因此乙個表只能包含乙個聚集索引。但該索引可以包含多個列 組合索引 就像 簿按姓氏和名字進行組織一樣...