天天看點

SQLSERVER中NULL位圖的作用

首先感謝宋沄劍提供的文章和sqlskill網站:www.sqlskills.com,看下面文章之前請先看一下下面兩篇文章

SQL Server誤區30日談-Day6-有關NULL位圖的三個誤區

char nchar varchar nvarchar的差別

在SQLSERVER内部有很多地方都使用到了位圖技術,包括執行計劃,資料庫系統頁面,複制,還有這篇文章說到的資料行中的NULL位圖

執行計劃中有位圖運算符

SQLSERVER中NULL位圖的作用

資料庫系統頁面有:DCM頁面、BCM頁面,詳細請看:SQL Server 2008 存儲結構之DCM、BCM

複制:Replication的犄角旮旯(三)--聊聊@bitmap(@bitmap 是binary類型,即二進制串;簡單來說,它是用來表示所操作的字段位置的參數,通過@bitmap,分發代理從distribution.dbo.msrepl_commands中讀取指令時(update操作),才會知道哪些列進行了更新;)

而這些位圖技術的作用無疑都是為了 标志位

标志哪些地方發生了變化,發生了變化的就标記為1,沒有發生變化的就标記為0

建立環境

建表

插入資料

檢視

SQLSERVER中NULL位圖的作用

建立DBCCResult表

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

View Code

檢視資料頁

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

資料頁内容

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

我們看到第一行的長度是11,第二行的長度是17

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

我們看第一行記錄長度11怎麽得出來的

在SQL Server頁中行實體存儲裡對資料行的各段進行了解釋

SQLSERVER中NULL位圖的作用

2個位元組行标頭存儲了狀态A和狀态B的資訊(2 bytes row header)

2個位元組存儲固定長度大小,因為一行記錄了有varchar這些不固定長度的資料類型(2 bytes for length of fixed length columns)

SQLSERVER需要知道int、datetime、decimal這些固定長度資料類型的大小

2個位元組的列數,用來存儲這個表一共有多少列(2 bytes for number of columns in the table)

1個位元組的null bitmap,(1 byte for null bitmap)

4個位元組存儲int型資料(4 bytes for int (1st column))

2+2+2+1+4=11

SQLSERVER中NULL位圖的作用

我們看第二行記錄長度17怎麽得出來的

2個位元組存儲資料行中的可變長度列數量,統計資料行中一共有多少列是nvarchar ,varchar類型的列( 2 bytes for number of variable length columns in the table)

2個位元組存儲可變長度偏移陣列,可變長度偏移陣列的公式

SQLSERVER中NULL位圖的作用

2*表格中可變長度資料類型的列數量,這個表隻有一列varchar,是以2*1=2,為什麽要有可變長度偏移陣列?我估計是因為可變長度的資料類型

存儲的資料是不固定的,是以要預留一些位置,當update varchar值的時候有足夠的位置(2 bytes for name column offset)

2個位元組存儲name列的值,為什麽用兩個位元組大家可以看一下char nchar varchar nvarchar的差別  2 bytes for name (你)

2+2+2+1+4+2+2+2=17

我們這裡不讨論資料占用空間的問題,這裡要說的是null bitmap

無論資料行中是否有null值,都會有一個位元組用來存儲null bitmap

而這個null bitmap是不是總是隻有一個位元組的長度,他的原理是什麼??

我畫了一下草圖

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

他在每一行記錄裡都存在,并且标記了哪一列是NULL,哪一列不是NULL

這樣在使用 len函數或者select 出表中的資料時候,先掃描NULL 位圖,遇到某一位為1就跳過不select出來,進而大大加快select的速度

len函數也是一樣,遇到某一位為1就傳回null

SQLSERVER中NULL位圖的作用

但是一個位元組隻有8位,也就是隻能标記表中8個列,如果一張表有10個列呢??

我們建立另外一張表

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

看一下他的資料頁

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

2個位元組行标頭存儲了狀态A和狀态B的資訊

2個位元組存儲固定長度大小,因為一行記錄了有varchar這些不固定長度的資料類型

2個位元組的列數,用來存儲這個表一共有多少列

4個位元組存儲int型資料

2個位元組存儲資料行中的可變長度列數量,統計資料行中一共有多少列是nvarchar ,varchar類型的列

20個位元組存儲可變長度偏移陣列,可變長度偏移陣列的公式2*10=20,因為有10個varchar類型列

9個位元組存儲name1~name10列的值,因為name1值為null,是以實際位元組長度為9個位元組即統計name2~name10的值,詳細可以再看一下

2個位元組的null bitmap

2+2+2+4+2+20+9+2=43

下面用草圖示範

SQLSERVER中NULL位圖的作用

 是以這裡NULL位圖的長度是根據你目前表中有多少列來決定的

SQLSERVER中NULL位圖的作用

testnull10varchar表有11個列相當于需要2個位元組的NULL 位圖了

關于行記錄屬性

在上面的實驗中testnullvarchar表第一行記錄和第二行記錄的行記錄屬性都不一樣,實際上這個行記錄屬性隻是指明

testnullvarchar表第二行記錄有可變長度類型資料,并且不為NULL,這并不意味着SQLSERVER掃描到第一行記錄的時候,

當發現record attributes(行記錄屬性)=NULL_BITMAP 就跳過第一行,不去讀取第一行記錄裡的資料

掃描到第二行記錄的時候,當發現record attributes(行記錄屬性)=NULL_BITMAP VARIABLE_COLUMNS知道第二行記錄有

可變長度資料并且不為NULL就去讀取第二行記錄裡的資料

論壇裡的rmiao大俠給出了下面解釋:

Null_bitmap in record attributes means this record contains null_bitmap field. Likewise,'null_bitmap variable_columns' means this record contains null_bitmap field with variable length columns.

不管資料行中是否有NULL值,建表的時候是否允許NULL,資料頁中的行都會有record attributes = NULL_BITMAP

而record attributes =NULL_BITMAP VARIABLE_COLUMNS 隻是說明了資料行有可變長度資料類型并且不為NULL

是以SQLSERVER在任何情況下都會去掃描這個NULL 位圖的,除了Record Attributes = No null bitmap

詳細可以看一下SQL Server誤區30日談-Day6-有關NULL位圖的三個誤區

SQLSERVER中NULL位圖的作用

證明

建立測試環境

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

testnullchar表,因為testnullchar表沒有可變長度資料類型,是以兩行資料都是NULL_BITMAP

SQLSERVER中NULL位圖的作用

testnotnullvarchar表,因為testnotnullvarchar表有可變長度資料類型,是以第二行為NULL_BITMAP VARIABLE_COLUMNS

SQLSERVER中NULL位圖的作用

testnotnullchar表,跟testnullchar表一樣

SQLSERVER中NULL位圖的作用

而NULL_BITMAP VARIABLE_COLUMNS隻是說明了資料行中有可變長度類型的資料,不是說某個字段就是可變長度資料類型

SQLSERVER中NULL位圖的作用

題外話

其實這篇文章是我前天看到某篇文章特别而寫的,覺得這個null bitmap要好好研究一下,以免被人誤導

本人不喜歡某些人以泰山壓頂之勢去評論别人,你知道的某些東西可能不一定正确的,而别人不知道的東西,日後一定會知道的,隻是時間問題

知道某樣東西的時間問題,遲早問題,或者這就是技術人的通病,自己技術厲害了,就XXXXXX!!!

SQLSERVER中NULL位圖的作用
SQLSERVER中NULL位圖的作用

如有不對的地方,歡迎大家拍磚o(∩_∩)o 哈哈