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

首頁 > 開發 > 綜合 > 正文

表上的DELETE操作

2024-07-21 02:46:30
字體:
來源:轉載
供稿:網友
表上的DELETE操作

在今天的文章里,我想給你快速展示下當我們從表里刪除記錄時,在SQL Server里發生了什么。首先我們來創建一個簡單的表,在8KB的頁上剛好能插入4條記錄。

1 -- Create a simple table where 4 records fit onto 1 page2 CREATE TABLE TestTable3 (4     Col1 INT IDENTITY(1, 1),5     Col2 CHAR(2000)6 )7 GO

接下來我們插入4條記錄,這樣的話一個頁剛好全部填滿。

 1 -- Insert 4 records 2 INSERT INTO TestTable VALUES 3 ( 4     REPLICATE('1', 2000) 5 ), 6 ( 7     REPLICATE('2', 2000) 8 ), 9 (10     REPLICATE('3', 2000)11 ),12 (13     REPLICATE('4', 2000)14 )15 GO

為了研究我們堆表的細節,我們使用DBCC PAGE命令來傾倒出分配的頁面。因此我們還要啟用3604跟蹤標志,這樣的話SQL Server從DBCC PAGE命令直接把結果輸入到我們SSMS的會話窗口:

1 -- Enable the Trace Flag 36042 DBCC TRACEON(3604)3 GO

我們可以使用DBCC IND命令返回所有分配給指定表或索引的頁:

1 -- Retrieve all pages of the table2 DBCC IND(DataModifications, TestTable, -1)3 GO

從輸出可以看到,2個頁屬于我們的表:數據頁本身,還有IAM(索引分配圖(index allocation map))頁。

我這里的頁號是118,通過DBCC PAGE命令傾倒出頁面:

1 -- Dump out one specific page2 DBCC PAGE (DataModifications, 1, 118, 2)3 GO

當你使用選項2的第3個參數傾倒,SQL Server返回你16進制的頁傾倒,包括在頁尾所謂的行偏移數組(Row Offset Array),不以任何方式影響數據。

行偏移數組指向在頁上的物理位置,即每條記錄存儲的地方。第1條記錄總是直接存儲在頁頭偏移量96(0x60h)的地方。你也會看到,行偏移數組是逆向增長的。現在讓我們從表里刪除第2條記錄:

1 -- Delete a record from the table2 DELETE FROM TestTable3 WHERE Col1 = 24 GO

通常這里你會期待記錄從頁里刪除。但事實上并不如此:當你再次執行DBCC PAGE命令時,你會看到在頁上老記錄的內容還是可以看到。在DELETE操作期間,SQL Server唯一做的是,在頁尾行偏移數組里,對應的槽無效了。

如你所見,第2個槽的偏移量是0x0,這是無效的,意味著我們的記錄被刪除了。在頁開始部分,你總會找到96 bytes的頁頭。現在讓我們從表里刪除其它的剩余3條記錄。

1 -- Delete all the remaining records from the table2 DELETE FROM TestTable3 GO

當你再次用DBCC PAGE命令查看頁,你會看到頁全部內容還是沒改變:每條記錄的每個數據在頁上還是物理存在的!但是在行偏移數據里每條記錄都指向偏移量0x0,這意味著每條記錄都被刪除。這與你的表是否使用了聚集索引無關——老數據在頁上一直存在。現在的問題是,SQL Server什么時候會初始化頁?當你現在插入新的記錄,SQL Server會覆蓋頁的原始內容。但在我們的情況里,這只是物理部分,第1條記錄存儲的位置。你還是能看到其它“刪除”的記錄內容。當你在頁尾看下行偏移數組,你會看到它已被SQL Server完全初始化了,也意味著你在行偏移數組里你現在只有1個槽了:

當你下次授權給程序sysadmin特權時,要考慮下這個情況了。使用合適的命令,這些程序還是能看到已經“刪除”的數據。

感謝關注!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 墨竹工卡县| 太和县| 衡山县| 新丰县| 昭通市| 嘉黎县| 平昌县| 海淀区| 长宁县| 扶余县| 岫岩| 红原县| 勐海县| 大余县| 和田县| 芒康县| 神池县| 赣榆县| 永州市| 敦化市| 磴口县| 嵊州市| 青铜峡市| 西平县| 平顺县| 平乐县| 南漳县| 天长市| 铜川市| 漠河县| 南安市| 城口县| 化德县| 石柱| 东城区| 贡嘎县| 岢岚县| 宁南县| 莎车县| 监利县| 民勤县|