Sql Server之旅——第九站 看看DML操作对索引的影响
我們都知道建索引是需要謹(jǐn)慎的,當(dāng)只有利大于弊的時(shí)候才適合建,同時(shí)也知道建索引是需要維護(hù)成本的,這個(gè)維護(hù)也就在于DML操作,下面具體看看到底DML對(duì)索引都有哪些內(nèi)幕。。。。
一:delete操作
現(xiàn)在大家都已經(jīng)知道索引是以B樹的形式存在,既然是B樹就要給大家展示一下葉子節(jié)點(diǎn)和分支結(jié)點(diǎn),先準(zhǔn)備點(diǎn)測(cè)試數(shù)據(jù),如下代碼:
CREATE TABLE Person(ID INT,NAME CHAR(200)) CREATE INDEX idx_Name ON Person(NAME)DECLARE @ch AS INT=65 WHILE @ch<=122 BEGININSERT INTO dbo.Person(ID,NAME)VALUES(@ch,REPLICATE(CHAR(@ch),200))SET @ch=@ch+1 END1. 葉子結(jié)點(diǎn)的變化
從上面的圖中大概可以看到,當(dāng)我插入完畢后,4個(gè)索引數(shù)據(jù)頁(yè)就出來了,其中PID=200的為分支數(shù)據(jù)頁(yè),其他三個(gè)為葉子節(jié)點(diǎn)數(shù)據(jù)頁(yè),編號(hào)分別為175,201,202,然后我就挑選第二個(gè)葉子節(jié)點(diǎn)數(shù)據(jù)頁(yè)201號(hào),看看里面的數(shù)據(jù)是啥樣的。
從數(shù)據(jù)頁(yè)中可以看到在201號(hào)數(shù)據(jù)頁(yè)中有18個(gè)槽位,當(dāng)然除了通過槽位看記錄條數(shù)之外,你還可以通過Pageheader中的m_slotCnt來觀察記 錄個(gè)數(shù),如下圖:
接下來,大家再看看slot0槽位的內(nèi)容是啥樣,如下代碼:
0000000000000000: 16484848 48484848 48484848 48484848 ?.HHHHHHHHHHHHHHH 0000000000000010: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000020: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000030: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000040: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000050: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000060: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000070: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000080: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000090: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000A0: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000B0: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000C0: 48484848 48484848 48970000 00010007 ?HHHHHHHHH....... 00000000000000D0: 00020000 ????????????????????????????....看到內(nèi)容之后,我們把這條記錄刪掉,然后快速的觀察數(shù)據(jù)頁(yè)的變化,很有意思的。。。。如下圖:
仔細(xì)觀察上面的圖,你會(huì)看到m_slotCnt=18。。。。你也看到m_ghostRecCnt=1,看這個(gè)名字你就知道是“幻象”的意思。。。正因?yàn)楸粯?biāo)記為幻象,是因?yàn)閟qlserver的后臺(tái)進(jìn)程會(huì)在某個(gè)時(shí)候把數(shù)據(jù)正真的刪除掉,比如你過個(gè)幾秒之后再查看就能看到真的被清除了。
2. 分支節(jié)點(diǎn)的變化
說完葉子節(jié)點(diǎn),然后我們繼續(xù)看看分支節(jié)點(diǎn),通過前面的博文,你應(yīng)該知道在分支節(jié)點(diǎn)中是依次保存著排序后的每個(gè)葉子節(jié)點(diǎn)中的最小值,剛好 我刪除了第二個(gè)葉子節(jié)點(diǎn)的第一個(gè)值,那這個(gè)值也正好保存在分支節(jié)點(diǎn)中,下面一個(gè)問題來了,我剛才刪除了ID=72的記錄,那這條記錄還會(huì)在分支節(jié)點(diǎn)中保存嗎???不用太興奮,用數(shù)據(jù)說話,繼續(xù)查看200號(hào)數(shù)據(jù)頁(yè)。
可以看到分支節(jié)點(diǎn)是不會(huì)刪除這條記錄的。
二:insert操作
索引都是按照索引列升序的,當(dāng)我insert的時(shí)候是不是需要給我插入到排序的指定位置呢???比如說我剛才刪除的HHH。。。數(shù)據(jù),這次我再insert的時(shí)候,是不是需要給我插入到第二個(gè)數(shù)據(jù)頁(yè)的slot0位置呢???下面繼續(xù)用數(shù)據(jù)說話。
INSERT INTO dbo.Person VALUES(72,REPLICATE(CHAR(72),200)) DBCC PAGE(Ctrip,1,201,1)Slot 0, Offset 0x101c, Length 212, DumpStyle BYTERecord Type = INDEX_RECORD Record Attributes = NULL_BITMAP Record Size = 212Memory Dump @0x000000000FE5B01C0000000000000000: 16686868 68686868 68686868 68686868 ?.hhhhhhhhhhhhhhh 0000000000000010: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000020: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000030: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000040: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000050: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000060: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000070: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000080: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 0000000000000090: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 00000000000000A0: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 00000000000000B0: 68686868 68686868 68686868 68686868 ?hhhhhhhhhhhhhhhh 00000000000000C0: 68686868 68686868 68c10000 00010002 ?hhhhhhhhh....... 00000000000000D0: 00020000 ????????????????????????????....Slot 1, Offset 0x1f04, Length 212, DumpStyle BYTERecord Type = INDEX_RECORD Record Attributes = NULL_BITMAP Record Size = 212Memory Dump @0x000000000FE5BF040000000000000000: 16484848 48484848 48484848 48484848 ?.HHHHHHHHHHHHHHH 0000000000000010: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000020: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000030: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000040: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000050: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000060: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000070: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000080: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 0000000000000090: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000A0: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000B0: 48484848 48484848 48484848 48484848 ?HHHHHHHHHHHHHHHH 00000000000000C0: 48484848 48484848 48c10000 00010015 ?HHHHHHHHH....... 00000000000000D0: 00020000 ????????????????????????????....從上面可以看到,當(dāng)我再次把刪除的”H"插入到數(shù)據(jù)頁(yè)的時(shí)候,發(fā)現(xiàn)“H”在201號(hào)數(shù)據(jù)頁(yè)的slot1位置了,有人就奇怪了,,,為什么不在slot0 的???
仔細(xì)想想確實(shí)是這么一個(gè)道理,那就是sql是不區(qū)別大小寫的,“H”和“h”對(duì)sqlserver來說都是一樣,這里還有一個(gè)問題就是數(shù)據(jù)頁(yè)分裂,比如說當(dāng)你insert的數(shù)據(jù)頁(yè)已滿,那這時(shí)候該怎么辦呢?sqlserver的手段就是數(shù)據(jù)頁(yè)分裂,將滿頁(yè)的一半數(shù)據(jù)導(dǎo)出到新分配的數(shù)據(jù)頁(yè),同樣我也可以做個(gè)例子。
CREATE TABLE Person(ID INT,NAME CHAR(5) DEFAULT 'xxxxx') CREATE INDEX idx_Name ON Person(NAME)DECLARE @i as int=1 WHILE @i<801 BEGININSERT INTO dbo.Person(ID) VALUES(@i)SET @i=@i+1 END接下來,我導(dǎo)出126號(hào)數(shù)據(jù)頁(yè)的記錄,可以看到它的范圍是1-449,如下圖:
下面我要做的事情就是插入一個(gè)ID在1-449范圍的一條記錄,這樣的話就會(huì)造成數(shù)據(jù)頁(yè)分裂了,對(duì)不對(duì)。
可以看到,現(xiàn)在多了一個(gè)192號(hào)數(shù)據(jù)頁(yè),是不是很有意思,哈哈~~ 然后我就非常好奇的再次導(dǎo)出126,192號(hào)數(shù)據(jù)頁(yè),看看數(shù)據(jù)是不是只剩 一半啦~~~
三:update操作
如果你看懂了上面的insert和delete,那么update就是這兩個(gè)操作的組合,也沒什么好說的。
好了,夜深了,洗洗睡了~
如您有更多問題與我互動(dòng),掃描下方進(jìn)來吧~
總結(jié)
以上是生活随笔為你收集整理的Sql Server之旅——第九站 看看DML操作对索引的影响的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Ids4实战】深究配置——用户信息操作
- 下一篇: 副业刚需? 恐怕并不靠谱!