日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server2008存储结构之聚集索引

發(fā)布時(shí)間:2023/12/31 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server2008存储结构之聚集索引 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

聚集索引即基于數(shù)據(jù)行的鍵值在表內(nèi)排序和存儲(chǔ)這些數(shù)據(jù)行。每個(gè)表只能有一個(gè)聚集索引,因?yàn)閿?shù)據(jù)行本身只能按一個(gè)順序存儲(chǔ)。

從某種程度上,聚集索引即數(shù)據(jù),這句話是有道理的;但正如同其他索引一樣,聚集索引也是按 B 樹結(jié)構(gòu)進(jìn)行組織的。既然是B樹組織,那么就有葉子結(jié)點(diǎn)和非葉子節(jié)點(diǎn)之分。聚集索引B 樹的頂端節(jié)點(diǎn)稱為根節(jié)點(diǎn);聚集索引中的底層節(jié)點(diǎn)稱為葉節(jié)點(diǎn)。在根節(jié)點(diǎn)與葉節(jié)點(diǎn)之間的任何索引級(jí)別統(tǒng)稱為中間級(jí)。在聚集索引中,葉節(jié)點(diǎn)包含基礎(chǔ)表的數(shù)據(jù)頁。根節(jié)點(diǎn)和中間級(jí)節(jié)點(diǎn)包含存有索引行的索引頁。每個(gè)索引行包含一個(gè)鍵值和一個(gè)指針,該指針指向 B 樹上的某一中間級(jí)頁或葉級(jí)索引中的某個(gè)數(shù)據(jù)行。每級(jí)索引中的頁均被鏈接在雙向鏈接列表中。

因此可以這么說,聚集索引的葉子結(jié)點(diǎn)存儲(chǔ)的是按聚集索引順序排列的數(shù)據(jù)本身,而中間結(jié)點(diǎn)和根節(jié)點(diǎn)則在維護(hù)索引和其層級(jí)。

對(duì)于某個(gè)聚集索引, sys.system_internals_allocation_units 中的 root_page 列指向該聚集索引某個(gè)特定分區(qū)的頂部。SQL Server 將從索引中向下移動(dòng)以查找與某個(gè)聚集索引鍵對(duì)應(yīng)的行。為了查找鍵的范圍,SQL Server 將在索引中移動(dòng)以查找該范圍的起始鍵值,然后用向前或向后指針在數(shù)據(jù)頁中進(jìn)行掃描。為了查找數(shù)據(jù)頁鏈的首頁,SQL Server 將從索引的根節(jié)點(diǎn)沿最左邊的指針進(jìn)行掃描。


drop table testUniqueCluster

drop table testNonUniqueCluster

CREATE TABLE testUniqueCluster

(

name CHAR(900),

remark CHAR(1100)

)

CREATE UNIQUE CLUSTERED INDEX ix_testUniqueCluster

ON testUniqueCluster(name)

INSERT INTO testUniqueCluster VALUES('B','BBB1')

INSERT INTO testUniqueCluster VALUES('A','AAA1')

CREATE TABLE testNonUniqueCluster

(

name CHAR(900),

remark CHAR(1100)

)

CREATE CLUSTERED INDEX ix_testNonUniqueCluster

ON testNonUniqueCluster(name)

INSERT INTO testNonUniqueCluster VALUES('B','BBB2')

INSERT INTO testNonUniqueCluster VALUES('B','BBB1')

INSERT INTO testNonUniqueCluster VALUES('A','AAA1')

SELECT c.name,a.type_desc,

total_pages,used_pages,data_pages,

testdb.dbo.f_get_page(first_page) first_page_address,

testdb.dbo.f_get_page(root_page) root_address,

testdb.dbo.f_get_page(first_iam_page) IAM_address

FROM sys.system_internals_allocation_units a,sys.partitions b,sys.objects c

WHERE a.container_id=b.partition_id and b.object_id=c.object_id

AND c.name in ('testUniqueCluster','testNonUniqueCluster')

TRUNCATE TABLE tablepage;

INSERT INTO tablepage EXEC ('DBCC IND(testdb,testUniqueCluster,1)');

INSERT INTO tablepage EXEC ('DBCC IND(testdb,testNonUniqueCluster,1)');

SELECT

b.name table_name,

CASE WHEN c.type=0 THEN '堆'

WHEN c.type=1 THEN '聚集'

WHEN c.type=2 THEN '非聚集'

ELSE '其他'

END index_type,

c.name index_name,

PagePID,IAMPID,ObjectID,IndexID,Pagetype,IndexLevel,

NextPagePID,PrevPagePID

FROM tablepage a,sys.objects b,sys.indexes c

WHERE A.ObjectID=b.object_id

AND A.ObjectID=c.object_id

AND a.IndexID=c.index_id

Name

Type_desc

Used_pages

Data_pages

First_page_address

Root_address

IAM_Address

testUniqueCluster

IN_ROW_DATA

2

1

1:233

1:233

1:234

testNonUniqueCluster

IN_ROW_DATA

2

1

1:235

1:235

1:236

下面我們用dbcc命令介紹一下聚集索引的構(gòu)造。

DBCC TRACEON(3604)

DBCC PAGE(testDB,1,233,1)

m_type = 1

5E3BC060: 1000d407 42202020 20202020 20202020 ?....B

....

5E3BC3E0: 20202020 20202020 42424231 20202020 ? BBB1

...

5E3BC830: 20202020 0200fc10 00d40741 20202020 ? .......A

...

5E3BCBB0: 20202020 20202020 20202020 20202041 ? A

5E3BCBC0: 41413120 20202020 20202020 20202020 ?AA1

...

5E3BD000: 20202020 20202020 20202002 00fc0000 ? .....

OFFSET TABLE:

Row - Offset

1 (0x1) - 96 (0x60)

0 (0x0) - 2103 (0x837)

DBCC PAGE(testDB,1,235,1)

5E3BC060: 1000d407 42202020 20202020 20202020 ?....B

...

5E3BC3E0: 20202020 20202020 42424232 20202020 ? BBB2

...

5E3BC830: 20202020 0300f830 00d40742 20202020 ? ...0...B

...

5E3BCBB0: 20202020 20202020 20202020 20202042 ? B

5E3BCBC0: 42423120 20202020 20202020 20202020 ?BB1

...

5E3BD000: 20202020 20202020 20202003 00f80100 ? .....

5E3BD010: df070100 00001000 d4074120 20202020 ?..........A

...

5E3BD390: 20202020 20202020 20202020 20204141 ? AA

5E3BD3A0: 41312020 20202020 20202020 20202020 ?A1

...

5E3BD7E0: 20202020 20202020 20200300 f8000021 ? .....!

OFFSET TABLE:

Row - Offset

2 (0x2) - 2103 (0x837)

1 (0x1) - 96 (0x60)

0 (0x0) - 4118 (0x1016)

其中紅顏色的部分為每行的行頭部分,藍(lán)顏色部分為每行的結(jié)尾部分。

大家可以看到m_type=1即數(shù)據(jù)頁面,大家應(yīng)該很奇怪吧,為什么明明是聚集索引,卻是數(shù)據(jù)頁面呢?正如上面所提到,聚集索引的葉子頁面即數(shù)據(jù)頁面。因?yàn)檫@個(gè)表只有2~3條記錄,所以root頁面還達(dá)不到需要分為B樹的程度,所以該root頁面也是葉子頁面。

我們首先來看一下1000d407的行頭部如何解釋

第0位

第1-3位

第4位

第5位

第6-7位

1個(gè)字節(jié)

2個(gè)字節(jié)

0

000

1

0

00

00

d407

10

00

2004

始終為0

0表示主記錄
3表示索引記錄
5表示幻影索引記錄

存在NULL位圖

存在變長字段

保留

狀態(tài)B保留

字段長度

即該行為不存在變長字段的主記錄,且字段長度為2004個(gè)字節(jié)。

那30 00d407該如何解釋呢?即00001100即存在變長字段的主記錄,我們的testNonUniqueCluster怎么會(huì)存在變長字段呢?

在該非唯一聚集索引表中,我們首先插入記錄B、BBB2記錄,再插入B、BBB1記錄,這個(gè)時(shí)候?qū)τ诜俏ㄒ凰饕绾稳プR(shí)別呢?SQL Server在重復(fù)行的行尾增加了8個(gè)額外的字節(jié),稍后我們?cè)俜治鲂形病?/p>

在testUniqueCluster表中正常的行尾為0200fc,其解釋如下0200表示該表有2個(gè)字段,fc則為1111 1100,即前2個(gè)字段不為空。

而對(duì)于testNonUniqueCluster表正常的行尾應(yīng)為0300 f8,其解釋如下0300表示該表有3個(gè)字段,f8則為1111 1000,即前3個(gè)字段不為空;很顯然SQL Server把非唯一索引的標(biāo)識(shí)符也當(dāng)做字段了;但的的確確因?yàn)锽、BBB2和A、AAA1在插入的時(shí)候是唯一的,所以不需要這個(gè)字段。

我們接下來看看B、BBB1行的尾部03 00f8 0100 df070100 0000,0300f8解釋同上,0100即1表示該表一共有1個(gè)變長字段,df07即2015變長字段結(jié)束的位置,最后四個(gè)字節(jié)0100 0000為非唯一索引的標(biāo)識(shí)符,換算成10進(jìn)制即1。

從頁面中記錄的順序我們其實(shí)可以看得出來,聚集索引的行的物理順序與行的實(shí)際存儲(chǔ)沒有太大關(guān)系,而是與記錄槽的順序的有關(guān)。

既然我們?cè)僬務(wù)摼奂饕?#xff0c;那就不能不說聚集索引的中間節(jié)點(diǎn)和根節(jié)點(diǎn)了,

為了簡化處理,我們使用testUniqueCluster來做進(jìn)一步的研究。

該表包含2個(gè)定長字段,合計(jì)2000字節(jié),加上相應(yīng)的頭部的4個(gè)管理字節(jié)和尾部的3個(gè)管理字節(jié),共計(jì)2007個(gè)字節(jié),頁頭還需要96個(gè)字節(jié),每行的偏移量需要2個(gè)字節(jié),所以單頁8192字節(jié)只能容納大概4條記錄。也就是說當(dāng)我們完成第五條記錄時(shí)就應(yīng)該產(chǎn)生分頁現(xiàn)象了。

INSERT INTO testUniqueCluster VALUES('C','CCC1')

INSERT INTO testUniqueCluster VALUES('D','DDD1')

INSERT INTO testUniqueCluster VALUES('E','EEE1')

TRUNCATE TABLE tablepage;

INSERT INTO tablepage EXEC ('DBCC IND(testdb,testUniqueCluster,1)');

SELECT

b.name table_name,

CASE WHEN c.type=0 THEN '堆'

WHEN c.type=1 THEN '聚集'

WHEN c.type=2 THEN '非聚集'

ELSE '其他'

END index_type,

c.name index_name,

PagePID,IAMPID,ObjectID,IndexID,Pagetype,IndexLevel,

NextPagePID,PrevPagePID

FROM tablepage a,sys.objects b,sys.indexes c

WHERE A.ObjectID=b.object_id

AND A.ObjectID=c.object_id

AND a.IndexID=c.index_id

以下為該表的詳細(xì)頁面分布

index_name

PagePID

IAMPID

IndexID

Pagetype

IndexLevel

NextPagePID

PrevPagePID

234

NULL

1

10

NULL

0

0

233

234

1

1

0

248

0

239

234

1

2

1

0

0

248

234

1

1

0

0

233

我們?cè)儆胹ys.system_internals_allocation_units來看一下該表的頁面概要信息。

name

total_pages

used_pages

data_pages

first_address

root_address

IAM_address

testUniqueCluster

4

4

2

1:233

1:239

1:234

從以上兩個(gè)表格,我們可以看出IAM頁面未發(fā)生變化,仍舊是第234頁面。

根節(jié)點(diǎn)頁面發(fā)生了變化,現(xiàn)在是第239頁面,pagetype=2,即索引頁面,新增加了一個(gè)數(shù)據(jù)頁面第248頁面,第233頁面仍繼續(xù)存在;同時(shí)在第248和233個(gè)頁面之間存在著互鏈的關(guān)系。

同時(shí)觀察一下數(shù)據(jù),發(fā)現(xiàn)在第233頁中存在A、AAA1;B、BBB1;C、CCC1;D、DDD1等4條記錄,而第248頁中則存在E、EEE1記錄,也就是說對(duì)于SQL Server來說索引的分裂應(yīng)該是以最小代價(jià)進(jìn)行,而不是完全均衡策略。

再讓我們用DBCC PAGE(1,testDB,239,3)觀察一下根節(jié)點(diǎn)的內(nèi)容。

FileId

PageId

Row

Level

ChildFileId

ChildPageId

name (key)

KeyHashValue

1

239

0

1

1

233

NULL

(6f4251ce1f81)

1

239

1

1

1

248

E

(201c8aeace10)

因?yàn)檫@是個(gè)索引的非葉子節(jié)點(diǎn),所以連表現(xiàn)形式都簡化了。

FieldId為當(dāng)前頁面的文件ID

PageId為當(dāng)前頁面的頁面ID

Row表示為當(dāng)前的slot槽

Level為1表示為當(dāng)前為非葉子節(jié)點(diǎn)

ChildFieldId表示為插槽號(hào)指向的頁面的文件ID

ChildPageId表示為插槽號(hào)指向的頁面的頁面ID

Name表示為當(dāng)前索引的鍵值

KeyHashValue為SQL Server鍵值的內(nèi)部表示的hash值。

即E右側(cè)的數(shù)據(jù)指向第248頁面,而左側(cè)的則指向第233頁面。

那么再讓我們插入4條記錄看看根頁面的變化。

INSERT INTO testUniqueCluster VALUES('C','CCC1')

INSERT INTO testUniqueCluster VALUES('D','DDD1')

INSERT INTO testUniqueCluster VALUES('E','EEE1')

DBCC PAGE(1,testDB,239,3)

FileId

PageId

Row

Level

ChildFileId

ChildPageId

name (key)

KeyHashValue

1

239

0

1

1

233

NULL

(6f4251ce1f81)

1

239

1

1

1

248

E

(201c8aeace10)

1

239

2

1

1

249

I

(201cbd800c11)

現(xiàn)在我們可以看到在根節(jié)點(diǎn)上又增加了一個(gè)新的鍵值I,凡是大于等于I的記錄均指向第249頁;結(jié)合前面的描述,我們可以得到下面的索引結(jié)構(gòu)變化示意圖。


總結(jié)

以上是生活随笔為你收集整理的SQL Server2008存储结构之聚集索引的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧洲三级视频 | 永久免费看mv网站入口亚洲 | 中国极品少妇xxxxx | 北条麻妃一二三区 | 超黄av| 呦呦视频在线观看 | 最新视频在线观看 | 成人欧美视频在线观看 | 日本久久片 | 亚洲制服丝袜一区 | 久青草国产在线 | 欧美激情免费观看 | 精品婷婷 | 懂色av一区二区三区免费 | 91国偷自产一区二区三区老熟女 | 超碰1997 | 黄色三及 | 日韩精品一区二区在线视频 | 成人三级黄色 | 欧美在线播放视频 | av成人免费观看 | 亚洲va在线∨a天堂va欧美va | 中文字幕在线资源 | 亚洲欧美一区二区三区孕妇 | 丰满人妻一区二区三区免费视频棣 | 日韩乱码人妻无码中文字幕 | 天天操女人 | 2一3sex性hd| 亚洲国产成人无码av在线 | 亚洲av无码专区在线电影 | cao在线| 国产乱强伦一区二区三区 | 欧美一二| 日本黄色激情视频 | 色94色欧美sute亚洲线路二 | 日产精品一区 | 欧美亚洲精品在线观看 | 精品一性一色一乱农村 | 国产精品久久久久无码av | 亚洲精品视频在线观看免费 | 国产精品av免费观看 | 久久人人爽人人爽人人 | 超碰在线91 | 那里有毛片看 | 久久久久久久久免费看无码 | 伊人222成人综合网 亚洲日本中文 | 制服丝袜影音先锋 | 美女隐私免费观看 | 午夜精品福利一区二区蜜股av | 国产精品你懂得 | 亚洲一区二区免费在线观看 | 三上悠亚人妻中文字幕在线 | 国产模特av私拍大尺度 | 在线观看成人黄色 | 东北少妇bbbb搡bbb搡 | 国产成人精品国内自产拍免费看 | 在线观看国产一区 | 911国产在线| 黄污视频在线观看 | 国产一级特黄aaa大片 | jizz在线看 | 欧美在线性爱视频 | 精品国产制服丝袜高跟 | 美国av导航 | 正在播放老肥熟妇露脸 | 大胸美女无遮挡 | 香港三级韩国三级日本三级 | 久草欧美 | 极品销魂美女一区二区三区 | 久久九色 | 国产视频污 | 九九热只有精品 | 欧美人妖另类 | 人妖性做爰aaaa | 大乳丰满人妻中文字幕日本 | www.在线观看麻豆 | 亚洲欧美在线免费观看 | 欧美青青草 | 色wwwwww| 欧美日本 | 在线观看黄 | 一级黄色免费视频 | 麻豆影片 | 成人激情四射 | 国产xxxx在线观看 | 午夜精品久久99蜜桃的功能介绍 | 午夜免费福利小视频 | 亚洲精选一区二区三区 | 国产特级黄色片 | 少妇太爽了 | 欧美视频在线不卡 | 五月激情六月丁香 | 久久精品超碰 | 操干视频| 深田咏美中文字幕 | av在线成人| 久久公开视频 | 福利社区一区二区 | 影音资源av|