SQL Server誤區(qū)30日談 第6天 有關(guān)NULL位圖的三個誤區(qū)
更新時間:2013年01月09日 19:18:29 作者:
NULL位圖是為了確定行中的哪一列是NULL值,哪一列不是。這樣做的目的是當Select語句后包含存在NULL值的列時,避免了存儲引擎去讀所有的行來查看是否是NULL,從而提升了性能
這樣還能減少CPU緩存命中失效的問題(點擊這個鏈接來查看CPU的緩存是如何工作的以及MESI協(xié)議)。下面讓我們來揭穿三個有關(guān)NULL位圖的普遍誤區(qū)。
誤區(qū) #6a:NULL位圖并不是任何時候都會用到
正確
就算表中不存在允許NULL的列,NULL位圖對于數(shù)據(jù)行來說會一直存在(數(shù)據(jù)行指的是堆或是聚集索引的葉子節(jié)點)。但對于索引行來說(所謂的索引行也就是聚集索引和非聚集索引的非葉子節(jié)點以及非聚集索引的葉子節(jié)點)NULL位圖就不是一直有效了。
下面這條語句可以有效的證明這一點:
CREATE TABLE NullTest (c1 INT NOT NULL);
CREATE NONCLUSTERED INDEX
NullTest_NC ON NullTest (c1);
GO
INSERT INTO NullTest VALUES (1);
GO
EXEC sp_allocationMetadata 'NullTest';
GO
你可以通過我的博文:Inside The Storage Engine: sp_AllocationMetadata - putting undocumented system catalog views to work.來獲得sp_allocationMetadata 的實現(xiàn)腳本。
DBCC TRACEON (3604);
DBCC PAGE (foo, 1, 152, 3); -- page ID from SP output
where Index ID = 0
DBCC PAGE (foo, 1, 154, 1); -- page ID from SP output
where Index ID = 2
GO
首先讓我們來看堆上這頁Dump出來的結(jié)果
Slot 0 Offset 0x60 Length 11
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP Memory Dump
@0x685DC060
再來看非聚集索引上的一頁Dump出來的結(jié)果:
Slot 0, Offset 0x60, Length 13, DumpStyle BYTE
Record Type = INDEX_RECORD Record Attributes = <<<<<<<
No null bitmap Memory Dump @0x685DC060
誤區(qū) #6b: NULL位圖僅僅被用于可空列
錯誤
當NULL位圖存在時,NULL位圖會給記錄中的每一列對應一位,但是數(shù)據(jù)庫中最小的單位是字節(jié),所以為了向上取整到字節(jié),NULL位圖的位數(shù)可能會比列數(shù)要多。對于這個問題.我已經(jīng)有一篇博文對此進行概述,請看:Misconceptions around null bitmap size.
誤區(qū) #6c:給表中添加額外一列時會立即導致SQL Server對表中數(shù)據(jù)的修改
錯誤
只有向表中新添加的列是帶默認值,且默認值不是NULL時,才會立即導致SQL Server對數(shù)據(jù)條目進行修改??傊?,SQL Server存儲引擎會記錄一個或多個新添加的列并沒有反映在數(shù)據(jù)記錄中。關(guān)于這點,我有一篇博文更加深入的對此進行了闡述:Misconceptions around adding columns to a table.
誤區(qū) #6a:NULL位圖并不是任何時候都會用到
正確
就算表中不存在允許NULL的列,NULL位圖對于數(shù)據(jù)行來說會一直存在(數(shù)據(jù)行指的是堆或是聚集索引的葉子節(jié)點)。但對于索引行來說(所謂的索引行也就是聚集索引和非聚集索引的非葉子節(jié)點以及非聚集索引的葉子節(jié)點)NULL位圖就不是一直有效了。
下面這條語句可以有效的證明這一點:
復制代碼 代碼如下:
CREATE TABLE NullTest (c1 INT NOT NULL);
CREATE NONCLUSTERED INDEX
NullTest_NC ON NullTest (c1);
GO
INSERT INTO NullTest VALUES (1);
GO
EXEC sp_allocationMetadata 'NullTest';
GO
你可以通過我的博文:Inside The Storage Engine: sp_AllocationMetadata - putting undocumented system catalog views to work.來獲得sp_allocationMetadata 的實現(xiàn)腳本。
讓我們通過下面的script來分別查看在堆上的頁和非聚集索引上的頁:
復制代碼 代碼如下:
DBCC TRACEON (3604);
DBCC PAGE (foo, 1, 152, 3); -- page ID from SP output
where Index ID = 0
DBCC PAGE (foo, 1, 154, 1); -- page ID from SP output
where Index ID = 2
GO
首先讓我們來看堆上這頁Dump出來的結(jié)果
復制代碼 代碼如下:
Slot 0 Offset 0x60 Length 11
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP Memory Dump
@0x685DC060
再來看非聚集索引上的一頁Dump出來的結(jié)果:
復制代碼 代碼如下:
Slot 0, Offset 0x60, Length 13, DumpStyle BYTE
Record Type = INDEX_RECORD Record Attributes = <<<<<<<
No null bitmap Memory Dump @0x685DC060
誤區(qū) #6b: NULL位圖僅僅被用于可空列
錯誤
當NULL位圖存在時,NULL位圖會給記錄中的每一列對應一位,但是數(shù)據(jù)庫中最小的單位是字節(jié),所以為了向上取整到字節(jié),NULL位圖的位數(shù)可能會比列數(shù)要多。對于這個問題.我已經(jīng)有一篇博文對此進行概述,請看:Misconceptions around null bitmap size.
誤區(qū) #6c:給表中添加額外一列時會立即導致SQL Server對表中數(shù)據(jù)的修改
錯誤
只有向表中新添加的列是帶默認值,且默認值不是NULL時,才會立即導致SQL Server對數(shù)據(jù)條目進行修改??傊?,SQL Server存儲引擎會記錄一個或多個新添加的列并沒有反映在數(shù)據(jù)記錄中。關(guān)于這點,我有一篇博文更加深入的對此進行了闡述:Misconceptions around adding columns to a table.
相關(guān)文章
使用sqlplus創(chuàng)建DDL和DML操作方法
這篇文章主要介紹了使用sqlplus創(chuàng)建DDL和DML操作方法,需要的朋友可以參考下2018-04-04SQL Server雙服務器架設并數(shù)據(jù)自動同步教程
自編程序由單機版改為網(wǎng)絡版后,使用范圍迅速擴大,如何保障數(shù)據(jù)庫萬無一失成為一個重要解決的問題于是想到架設雙服務器并數(shù)據(jù)自動同步,詳細步驟如下2012-11-11MSSQL中進行SQL除法運算結(jié)果為小數(shù)卻顯示0的解決方法
這篇文章主要介紹了MSSQL中進行SQL除法運算結(jié)果為小數(shù)卻顯示0的解決方法,需要的朋友可以參考下2015-10-10Linux環(huán)境中使用BIEE 連接SQLServer業(yè)務數(shù)據(jù)源
biee11g默認安裝了mssqlserver的數(shù)據(jù)驅(qū)動,不需要在服務器端進行重新安裝,配置過程主要基于ODBC實現(xiàn),本文主要介紹客戶端為windows、服務端為linux系統(tǒng)的配置過程。2014-07-07實例講解sql server排名函數(shù)DENSE_RANK的用法
這篇文章主要以一個實例講解了sql server排名函數(shù)DENSE_RANK的用法,感興趣的小伙伴們可以參考一下2016-03-03SQL Server阻止保存修改表結(jié)構(gòu)的解決方法
修改DeUser表中列的數(shù)據(jù)類型從varchar修改為int時,進行保存時彈出的提示框,阻止保存修改表結(jié)構(gòu),怎么辦?這篇文章就為大家詳細介紹了解決SQL Server阻止保存修改表結(jié)構(gòu)問題的方法,感興趣的小伙伴們可以參考一下2016-05-05SQL SERVER數(shù)據(jù)庫表記錄只保留N天圖文教程
本篇向大家介紹SQL Server 2008 R2數(shù)據(jù)庫中數(shù)據(jù)表保留10天記錄,需要的朋友可以參考下2015-09-09