国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

INDEX--從數據存放的角度看索引2

2024-07-21 02:48:19
字體:
來源:轉載
供稿:網友
INDEX--從數據存放的角度看索引2

在上次<INDEX--從數據存放的角度看索引>中,我們說到"唯一非聚集索引"和“非唯一非聚集索引”在存儲上有一個明顯的差別:唯一非聚集索引的非葉子節點上不會包含RID的數據,讓我們繼續來深挖一下。

準備測試數據:

CREATE TABLE TB1(    C1 INT,    C2 INT,    C3 INT)GOCREATE UNIQUE CLUSTERED INDEX IDX_C1 ON TB1(C1)GOCREATE UNIQUE INDEX IDX_C2 ON TB1(C2)GOCREATE INDEX IDX_C3 ON TB1(C3)GOINSERT INTO TB1(C1,C2,C3)VALUES(1,1,1)GOINSERT INTO TB1(C1,C2,C3)VALUES(2,2,2)GOINSERT INTO TB1(C1,C2,C3)VALUES(3,3,3)

索引編號如下:

再通過DBCC IND和DBCC PAGE來查看頁情況

唯一非聚集索引IDX_C2的數據頁:

非唯一非聚集索引IDX_C3的數據頁:

以上兩張圖有個明顯的區別是C1和C1(key),難道在“非唯一非聚集索引”中,“聚集索引鍵”也被放到“非聚集索引鍵”中并且參與排序啦?

相信很多DBA的朋友都遇到這樣的問題,要按照某些狀態值來查找數據,而這些狀態值是一個很小的集合(數量很小),如查找狀態值為1的最大訂單號

SELECT TOP(1)* FROM dbo.OrdersWHERE OrderState=1ORDER BY OrderID DESC 

雖然OrderID為主鍵和唯一聚集索引,但按照OrderID來查找,可能需要進行大范圍CLUSTERED INDEX SEEK才能找到滿足條件OrderState=1的數據,因此盡管OrderState的可選擇性較低,我們還是會對其建立索引,那么問題來了?我們索引該建成什么樣呢?是建成:

CREATE INDEX IDX_OrderStateON dbo.Orders(    OrderState)

還是建成:

CREATE INDEX IDX_OrderStateON dbo.Orders(    OrderState,    OrderID)

曾經我想當然地認為必須建成第二種方式,因為還需要對OrderID進行排序取TOP(1),但經過測試,神奇地發現兩種方式的效率一樣,無論“非唯一非聚集索引鍵”里有沒有包含“聚集索引鍵”,都會對“非唯一非聚集索引鍵”+“聚集索引鍵”進行排序。

思考這樣一個問題,假設對“非唯一非聚集索引鍵”,僅僅對其定義的鍵進行排序,如OrderState,而滿足OrderState=0的可能有1億數據,在進行數據更新的時候,首先更新聚集索引,并依次更新非聚集索引,更新索引數據首先要定位數據行才能更新,因此需要掃描這1億數據才能找到目標行,顯然這是不可接受的設計。

對于"唯一非聚集索引"來說,因為可以通過索引鍵便可以快速定位到索引數據行,且每個鍵值只會存在一行,因此失去了對“聚集索引鍵”進行排序的意義。

BTW, 也可以通過觀察相同鍵值下行位置(slotid)和插入順序來發現數據按照聚集索引鍵排序。

--===========================================================================

總結:

1. 對于“非唯一非聚集索引”,索引數據實際上是按照“非唯一非聚集索引鍵”+“聚集索引鍵”進行排序后存放的;

2. 對于“唯一非聚集索引”,索引數據實際上是按照“唯一非聚集索引鍵”進行排序后存放的;

3. 所有非聚集索引的葉子節點上都會存放RID的數據,但唯一非聚集索引的非葉子節點上不會包含RID的數據;

--===========================================================================

好好讀書。。。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台江县| 辽宁省| 巴南区| 宁化县| 大兴区| 宜宾县| 嘉黎县| 什邡市| 廊坊市| 察雅县| 大厂| 郯城县| 溧水县| 兴山县| 茂名市| 五大连池市| 黄陵县| 临沭县| 齐河县| 仁布县| 太和县| 松原市| 上犹县| 全南县| 石首市| 旬阳县| 宽城| 西和县| 吉林省| 新营市| 象州县| 射阳县| 平乐县| 石阡县| 彰化县| 海林市| 沅江市| 新安县| 乌兰县| 泾阳县| 理塘县|