亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

探秘空值位圖掩碼(NULL bitmap mask)

2024-07-21 02:46:41
字體:
來源:轉載
供稿:網友
探秘空值位圖掩碼(NULL bitmap mask)

這篇文章我想談下空值位圖掩碼(NULL bitmap mask) ,并揭開它的神秘面紗。空值位圖掩碼是在存儲引擎層為列是否存儲NULL值進行編碼。它是一個簡單的位圖掩碼,如果值是1的話,表示這列有NULL值,如果是0的話,表示這列有具體的值(非NULL值)。

這樣的解釋聽起來非常直接,但當我們進一步分析時,用這個方法還是有啟發性的。首先我們來看看數據行的組合結構,這是存儲引擎用來在磁盤上存儲記錄的結構。結構如下圖所示:

這個格式被稱為定長變量格式(FixedVar format),因為SQL Server總是先存儲定長列(像INT,CHAR),再存儲變長列(像VARCHAR)。從圖中我們可以看到,SQL Server以存儲2 bytes的狀態位開始,接著用2 bytes存儲由行頭到定長列結尾長度(包含所有定長列數據)。然后用2 bytes存儲列個數,緊隨其他的就是真正的空值位圖掩碼(NULL bitmap mask)。

所有的一切第一眼看起來都很合理,但我們再仔細看下的話,我們就開始思考,并且你可能會問:為什么SQL Server在每條數據行里存儲具體的列數?對于每條數據行,列數都不是一樣的么?為什么SQL Server要存儲這些冗余的數據?

第1個答案是非常簡單和有邏輯性的:SQL Server需要列數來計算用作實際空值位圖掩碼(NULL bitmap mask)的字節數。小于等于8列的表需要1 byte,9到16列需要 2 bytes,17到24列需要3 bytes,以此類推。明白了么?但在表里每條記錄的列數必須是一樣的!

我們來看第2個用實例分析的技術性正確答案:首先,你要知道空值位圖掩碼(NULL bitmap mask)是用在數據引擎級別,即當前記錄中的列數。這就是說SQL Server在物理行可以存儲不同數量的列。額,好像說的有點含糊不清…………物理數據行列數和表元數據層(sys.dolumns)里列數并不一致。這些也是SQL Server內部的真正不同層級。

因此在什么情況下這些層級間會彼此不相等呢?很簡單:當你往表里增加列的時候!如果你加的列是NULL還是NOT NULL,SQL Server會作出完全不同的區別。當你增加一個新的NULL列到表時,SQL Server只更新表元數據層,一點也不接觸到存儲引擎層。也就是說當你增加一個NULL列時,所有的記錄物理存儲上不發生任何改變。另一方面,當你增加一個NOT NULL列時,SQL Server會更新表元數據層,同時也會更新存儲引擎層,這就是說,SQL Server會接觸并重寫表里的每一條記錄,在那里你增加了一個NOT NULL列。這會帶來性能上的巨大區別!因此SQL Server需要在每條數據記錄里存儲具體的列數,因為這里的列數不能和表元數據層的列數同步。

我們來拿具體的例子來詳細分析下。這個例子我們創建了一個簡單的含8列的表,SQL Server需要使用1 bytes來作為空值位圖掩碼(NULL bitmap mask)

 1 CREATE TABLE TestTable 2 ( 3     Column1 INT IDENTITY(1, 1) NOT NULL, 4     Column2 CHAR(600) NOT NULL, 5     Column3 CHAR(600) NOT NULL, 6     Column4 CHAR(600) NOT NULL, 7     Column5 CHAR(600) NOT NULL, 8     Column6 VARCHAR(600) NOT NULL, 9     Column7 VARCHAR(600) NOT NULL,10     Column8 VARCHAR(600) NOT NULL11 )12 GO

然后,我們往表里插入2條記錄:

 1 INSERT INTO TestTable VALUES 2 ( 3     REPLICATE('2', 600), 4     REPLICATE('3', 600), 5     REPLICATE('4', 600), 6     REPLICATE('5', 600), 7     REPLICATE('6', 600), 8     REPLICATE('7', 600), 9     REPLICATE('8', 600)10 ),11 (12     REPLICATE('2', 600),13     REPLICATE('3', 600),14     REPLICATE('4', 600),15     REPLICATE('5', 600),16     REPLICATE('6', 600),17     REPLICATE('7', 600),18     REPLICATE('8', 600)19 )20 GO

我們通過DBCC PAGE命令查看下具體的數據頁:

1 DBCC IND(ALLOCATIONDB, TestTable, -1)2 GO

1 DBCC TRACEON(3604)2 GO3 DBCC PAGE(ALLOCATIONDB, 1, 24993, 1)4 GO5 6 DBCC TRACEON(3604)7 GO8 DBCC PAGE(ALLOCATIONDB, 1, 24995, 1)9 GO

可以看到,每條記錄的長度是 4129 bytes(4204 bytes 數據+ 7 bytes 行開銷+ 2 bytes 變長列個數 + 3 * 2 bytes 每個變長列結束位置的偏移量)。

現在我們往表里加一個新的NULL列:

1 ALTER TABLE TestTable ADD Column9 CHAR(600) NULL2 GO

這是表里的第9列,也就是說SQL Server對于這個列數需要2 bytes。但是 SQL Server并不在存儲引擎層改變物理數據行,因為我們只加了一個NULL列。SQL Server不需要在存儲引擎層做任何處理。我們可以通過查看數據頁來驗證下:

記錄還是同樣4219 bytes的長度,但是我們邏輯上已經在表上加了1列。現在我們來更新表的1條記錄,這樣的話,新加列就有具體值了:

1 UPDATE TestTable SET Column9 = REPLICATE('9', 600)2 WHERE Column1 = 13 GO

當你查看表里第2條記錄的數據頁時,記錄大小還是原來的4219 bytes。

1 DBCC TRACEON(3604)2 GO3 DBCC PAGE(ALLOCATIONDB, 1, 24995, 1)4 GO

你現在創建了一個場景:SQL Server在數據行內部存儲了不同長度的空值位圖掩碼(NULL bitmap mask)。這就是說你有定長列的表,在存儲引擎級別,卻有不同長度的行大小!很有趣,是不是?

現在我們刪除表并重建,繼續往表里插入2條記錄:

 1 DROP TABLE dbo.TestTable 2  3 CREATE TABLE TestTable 4 ( 5     Column1 INT IDENTITY(1, 1) NOT NULL, 6     Column2 CHAR(600) NOT NULL, 7     Column3 CHAR(600) NOT NULL, 8     Column4 CHAR(600) NOT NULL, 9     Column5 CHAR(600) NOT NULL,10     Column6 VARCHAR(600) NOT NULL,11     Column7 VARCHAR(600) NOT NULL,12     Column8 VARCHAR(600) NOT NULL13 )14 GO15 16 INSERT INTO TestTable VALUES17 (18     REPLICATE('2', 600),19     REPLICATE('3', 600),20     REPLICATE('4', 600),21     REPLICATE('5', 600),22     REPLICATE('6', 600),23     REPLICATE('7', 600),24     REPLICATE('8', 600)25 ),26 (27     REPLICATE('2', 600),28     REPLICATE('3', 600),29     REPLICATE('4', 600),30     REPLICATE('5', 600),31     REPLICATE('6', 600),32     REPLICATE('7', 600),33     REPLICATE('8', 600)34 )35 GO

現在我們往表里增加一個NOT NULL列:

1 ALTER TABLE TestTable ADD Column9 CHAR(600) NOT NULL2 DEFAULT REPLICATE('9', 600)3 GO

現在,SQL Server需要在存儲引擎層改變每條記錄,因為新列的默認值必須被增加(當你表里已經有記錄存儲時,新加列必須要定義一個默認值),而且SQL Server需要擴展空值位圖掩碼(NULL bitmap mask)。

 1 DBCC IND(ALLOCATIONDB, TestTable, -1) 2 GO 3  4 DBCC TRACEON(3604) 5 GO 6 DBCC PAGE(ALLOCATIONDB, 1, 24993, 1) 7 GO 8  9 DBCC TRACEON(3604)10 GO11 DBCC PAGE(ALLOCATIONDB, 1, 24995, 1)12 GO

當你處理大表,給表增加NOT NULL列時,這個現象會導致嚴重的性能問題。想象下我們往表里插入100萬條記錄。當我們增加NULL列時,SQL Server只需要幾毫秒,因為只進行元數據修改操作。但當我們往表里增加NOT NULL列時,SQL Server待ALTER TABLE操作完成需要花費40秒!在處理大表,往表里增加NOT NULL列,這的確是個非常嚴重的性能降級?。?/p>

希望你現在已經理解了為什么SQL Server在存儲引擎層對每條記錄存儲具體的列數,還有在SQL Server里,當你往大表里增加NOT NULL列,會出現嚴重的性能問題。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美风情在线观看| 69国产精品成人在线播放| 69视频在线播放| 国产精品第一页在线| 亚洲最大中文字幕| 精品福利在线视频| 久久不射热爱视频精品| 色综合久综合久久综合久鬼88| 国产精品成人aaaaa网站| 欧美日韩一区二区三区| 国产成人精品日本亚洲专区61| 最新国产精品拍自在线播放| 欧美亚洲国产视频| 韩国一区二区电影| 日韩美女在线播放| 亚洲伊人成综合成人网| 国产精品video| 欧美国产中文字幕| 中文字幕亚洲一区二区三区| 成人免费网站在线看| 亚洲老司机av| 国产精品色午夜在线观看| 2019中文字幕在线免费观看| 精品中文字幕在线2019| 精品爽片免费看久久| 亚洲电影av在线| 久久久91精品国产一区不卡| 久久久女人电视剧免费播放下载| 国产午夜精品视频免费不卡69堂| 欧美韩日一区二区| 国产在线拍偷自揄拍精品| 日韩精品高清视频| 欧美美女15p| 欧美噜噜久久久xxx| 欧美富婆性猛交| 精品中文字幕在线观看| 永久555www成人免费| 成人有码在线视频| 精品久久久久久久久国产字幕| 久久躁日日躁aaaaxxxx| 色综合久久中文字幕综合网小说| 日韩美女视频免费在线观看| 久久亚洲精品中文字幕冲田杏梨| 亚洲乱码国产乱码精品精天堂| 国产精品一区电影| 国产精品视频网| 精品久久久中文| 国产区精品视频| 国产一区二区三区在线免费观看| 国产中文欧美精品| 久久偷看各类女兵18女厕嘘嘘| 国产精品色婷婷视频| 亚洲成人黄色网址| 成人免费自拍视频| 国产精品第一第二| 亚洲自拍偷拍区| 成人淫片在线看| 国产欧美日韩精品在线观看| yw.139尤物在线精品视频| 欧美精品成人在线| 在线日韩精品视频| 精品久久久久久亚洲国产300| 97超级碰碰碰久久久| 国产在线精品播放| 日韩精品在线第一页| 国产亚洲在线播放| 91系列在线播放| 日产精品99久久久久久| 国内偷自视频区视频综合| 欧美第一黄色网| 欧美成人免费全部观看天天性色| 91探花福利精品国产自产在线| 2021国产精品视频| 亚洲国产另类 国产精品国产免费| 国产精品爱啪在线线免费观看| 91久久精品国产91性色| 俺去亚洲欧洲欧美日韩| 欧美日韩另类字幕中文| 国产精品激情自拍| 亚洲新中文字幕| 日韩极品精品视频免费观看| 欧美日韩亚洲一区二区三区| 热久久美女精品天天吊色| 精品久久久久久久久久久久久| 欧美视频不卡中文| 亚洲人成77777在线观看网| 亚洲激情国产精品| 亚洲一区二区免费| 国产成人免费av| 精品一区精品二区| 亚洲欧美成人网| 91tv亚洲精品香蕉国产一区7ujn| 日本一区二区三区在线播放| 成人有码在线视频| 在线免费观看羞羞视频一区二区| 久久久极品av| 色综合老司机第九色激情| 富二代精品短视频| 国产精品久久久精品| 欧美性猛交xxxx久久久| www.欧美视频| 久久亚洲精品国产亚洲老地址| 成人春色激情网| 亚洲精品一区av在线播放| 91精品国产高清自在线| 国产欧美精品日韩| 国产中文日韩欧美| 国产精品极品在线| 国产成人中文字幕| 色在人av网站天堂精品| 亚洲男人第一网站| 欧美日韩国产在线看| 亚洲一区中文字幕| 88xx成人精品| 亚洲精品欧美日韩专区| 色yeye香蕉凹凸一区二区av| 国产精品96久久久久久| 国产精品久久久久一区二区| 国产在线精品一区免费香蕉| 九九久久久久久久久激情| 92看片淫黄大片看国产片| 成人网在线免费看| 国产xxx69麻豆国语对白| 亚洲成色www8888| 成人精品网站在线观看| 国产精品免费视频xxxx| 粗暴蹂躏中文一区二区三区| 欧美性猛交xxxx久久久| 欧美性少妇18aaaa视频| 久久久久这里只有精品| 亚洲四色影视在线观看| 欧美激情国产日韩精品一区18| 国产精品网站大全| 97在线精品国自产拍中文| 午夜精品国产精品大乳美女| 成人免费淫片aa视频免费| 欧美放荡办公室videos4k| 日韩天堂在线视频| 国产91精品视频在线观看| 亚洲视频在线免费看| 亚洲美女中文字幕| 久久国产视频网站| 中日韩美女免费视频网站在线观看| 久久精品国产免费观看| 久久久久久有精品国产| 久久人人97超碰精品888| 亚洲美女精品久久| 国产精品999999| 亚洲韩国欧洲国产日产av| 日韩av在线不卡| 欧美精品在线网站| 亚洲精品aⅴ中文字幕乱码| 永久免费精品影视网站| 在线国产精品视频| 黑人狂躁日本妞一区二区三区| 在线观看成人黄色| 久久99热这里只有精品国产| 欧美日韩国产123| 精品自在线视频| 精品久久久91| 中文字幕在线日韩| 日韩免费av在线| 国产91|九色| 久久久天堂国产精品女人|