SQL SERVER 聚集索引 非聚集索引 區別

2022-07-05 01:45:14 字數 2842 閱讀 3055

一、理解索引的結構

索引在資料庫中的作用類似於目錄在書籍中的作用,用來提高查詢資訊的速度。使用索引查詢資料,無需對整表進行掃瞄,可以快速找到所需資料。微軟的sql server提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclustered index,也稱非聚類索引、非簇集索引)。

sql server 中資料儲存的基本單位是頁(page)。資料庫中的資料檔案(.mdf 或 .ndf)分配的磁碟空間可以從邏輯上劃分成頁(從 0 到 n 連續編號)。磁碟 i/o 操作在頁級執行。也就是說,sql server 每次讀取或寫入資料的最少資料單位是資料頁。

下面我們先簡單的了解一下索引的體系結構:

1. 聚集索引結構

在 sql server 中,索引是按 b 樹結構進行組織的。

聚集索引單個分割槽中的結構:

--建立useradddate聚集索引

create clustered index [ix_adddate] on [user]

( [adddate] asc

)

聚集索引(clustered index)特點2. 非聚集索引結構

非聚集索引與聚集索引具有相同的 b 樹結構,它們之間的顯著差別在於以下兩點:

1. 基礎表的資料行不按非聚集鍵的順序排序和儲存。

2. 非聚集索引的葉層是由索引頁而不是由資料頁組成。

下圖示意了單個分割槽中的非聚集索引結構:

包含列的索引

通過將包含列(稱為非鍵列)新增到索引的葉級,可以擴充套件非聚集索引的功能。鍵列儲存在非聚集索引的所有級別,而非鍵列僅儲存在葉級別。

下面舉個簡單的例子來說明一下聚集索引和非聚集索引的區別:

我們有一本漢語字典,可以把它的正文本身看做是乙個聚集索引,它是按照漢字拼音的開頭字母排序的,不再需要查詢其他目錄。當遇到不認識的字時,需要結合「部首目錄」和「檢字表」, 先找到目錄中的結果,然後再翻到您所需要的頁碼。通過這種方法查到的目錄中字的排序並不是真正的正文的排序方法。把這種看做是乙個非聚集索引。

另外,請注意每個表只能有乙個聚集索引。

--建立useradddate非聚集索引

create nonclustered index [ix_adddate] on [user]

([adddate] asc

)非聚集索引 (unclustered index) 特點

二、選擇建立哪種索引

1. 何時建立聚集索引更能提高效能

clustered index會提高大多數table的效能,尤其是當它滿足以下條件時:

獨特, 狹窄, 持續增長的,最好是只向上增加。例如:

2. 非聚集索引提高效能的方法

非聚集索引由於b樹的節點不是具體資料頁,有時候由於這個原因,會導致非聚集索引甚至不如表遍歷來的快。但是,非聚集索引有個特性,如果你要查詢的內容,在非聚集索引中以及被覆蓋到了,則不需要繼續到聚集索引,或者rid(heap結構中的行識別符號)中去尋找資料了,這時候就可以很大的提高效能,這就是覆蓋面(covering) 的問題。

由於聚集索引葉子節點就是具體資料,所以聚集索引的覆蓋率是100%, 通過提高覆蓋面來提高效能的問題也就只有非聚集索引(nonclustered indexes)才存在。

當查詢中所有的columns都包括在index上時,我們說這 index covers the query. columns的順序在此不重要(select 時候的順序不重要,但是index 建立的順序可得小心了)。

在 sql server 2005 中,為了提高這種 covering 帶來的好處,甚至可以通過將非鍵列新增到非聚集索引的葉級別來擴充套件非聚集索引的功能。

補充:只有查詢在具有高度選擇性的情況下,非聚集索引才有優勢。

四、主鍵和聚集索引的比較

以下是一些大眾點評網中測試使用的示例:

checkpoint

dbcc dropcleanbuffers

set statistics io on

declare @d datetime

set @d=getdate()

select * from user where adddate>'2008-06-01' and adddate

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())

--(45077 行受影響)

--表'user'。掃瞄計數1,邏輯讀取1103 次,物理讀取2 次,預讀1090 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。

--2543

checkpoint

dbcc dropcleanbuffers

set statistics io on

declare @d datetime

set @d=getdate()

select * from user with (index=ix_adddate) where adddate>'2008-06-01' and adddate

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())

--(45077 行受影響)

--表'user'。掃瞄計數1,邏輯讀取45165 次,物理讀取133 次,預讀141 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。

--3860

五、使用索引的代價

sqlserver 聚集索引 非聚集索引

聚集索引是一種對磁碟上實際資料重新組織以按指定的一列或者多列值排序。像我們用到的漢語字典,就是乙個聚集索引。換句話說就是聚集索引會改變資料庫表中資料的存放順序。非聚集索引不會重新組織表中的資料,而是對每一行儲存索引列值並用乙個指標指向資料所在的頁面。乙個值指向多行等於該值的資料 sqlserver預...

sql server聚集索引與非聚集索引

於 sql server聚集索引與非聚集索引 筆記 雜,淺顯理解 聚集索引按順序查詢 拼音目錄 非聚集索引不按順序查詢 部首目錄 每個表只能有乙個聚集索引,因為目錄只能按照一種方法進行排序。返回某範圍內的資料一項。比如您的某個表有乙個時間列,恰好您把 聚合索引建立在了該列,這時您查詢2004年1月1...

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

非聚集索引和聚集索引的區別 不在不會詳細說明非聚集索引和聚集索引的結構有什麼不一樣,因為這種東西網上已經說的很多了。乙個表一旦建立了聚集索引,那麼那張表就是一張被b樹重新組織過的表。而沒聚集索引表就是乙個堆表。什麼是b樹,什麼是堆表就不解釋了。小弟對,非聚集索引狀況下 和 聚集索引狀況下的 常量繫結...