SQL Server误区30日谈 第6天 有关NULL位图的三个误区
程序员文章站
2023-11-26 19:59:04
这样还能减少cpu缓存命中失效的问题(点击这个链接来查看cpu的缓存是如何工作的以及mesi协议)。下面让我们来揭穿三个有关null位图的普遍误区。 误区 #6a:null...
这样还能减少cpu缓存命中失效的问题(点击这个链接来查看cpu的缓存是如何工作的以及mesi协议)。下面让我们来揭穿三个有关null位图的普遍误区。
误区 #6a:null位图并不是任何时候都会用到
正确
就算表中不存在允许null的列,null位图对于数据行来说会一直存在(数据行指的是堆或是聚集索引的叶子节点)。但对于索引行来说(所谓的索引行也就是聚集索引和非聚集索引的非叶子节点以及非聚集索引的叶子节点)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 的实现脚本。
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出来的结果
slot 0 offset 0x60 length 11
record type = primary_record record attributes = null_bitmap memory dump
@0x685dc060
再来看非聚集索引上的一页dump出来的结果:
slot 0, offset 0x60, length 13, dumpstyle byte
record type = index_record record attributes = <<<<<<<
no null bitmap memory dump @0x685dc060
误区 #6b: null位图仅仅被用于可空列
错误
当null位图存在时,null位图会给记录中的每一列对应一位,但是数据库中最小的单位是字节,所以为了向上取整到字节,null位图的位数可能会比列数要多。对于这个问题.我已经有一篇博文对此进行概述,请看:misconceptions around null bitmap size.
误区 #6c:给表中添加额外一列时会立即导致sql server对表中数据的修改
错误
只有向表中新添加的列是带默认值,且默认值不是null时,才会立即导致sql server对数据条目进行修改。总之,sql server存储引擎会记录一个或多个新添加的列并没有反映在数据记录中。关于这点,我有一篇博文更加深入的对此进行了阐述:misconceptions around adding columns to a table.
误区 #6a:null位图并不是任何时候都会用到
正确
就算表中不存在允许null的列,null位图对于数据行来说会一直存在(数据行指的是堆或是聚集索引的叶子节点)。但对于索引行来说(所谓的索引行也就是聚集索引和非聚集索引的非叶子节点以及非聚集索引的叶子节点)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 的实现脚本。
让我们通过下面的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出来的结果
复制代码 代码如下:
slot 0 offset 0x60 length 11
record type = primary_record record attributes = null_bitmap memory dump
@0x685dc060
再来看非聚集索引上的一页dump出来的结果:
复制代码 代码如下:
slot 0, offset 0x60, length 13, dumpstyle byte
record type = index_record record attributes = <<<<<<<
no null bitmap memory dump @0x685dc060
误区 #6b: null位图仅仅被用于可空列
错误
当null位图存在时,null位图会给记录中的每一列对应一位,但是数据库中最小的单位是字节,所以为了向上取整到字节,null位图的位数可能会比列数要多。对于这个问题.我已经有一篇博文对此进行概述,请看:misconceptions around null bitmap size.
误区 #6c:给表中添加额外一列时会立即导致sql server对表中数据的修改
错误
只有向表中新添加的列是带默认值,且默认值不是null时,才会立即导致sql server对数据条目进行修改。总之,sql server存储引擎会记录一个或多个新添加的列并没有反映在数据记录中。关于这点,我有一篇博文更加深入的对此进行了阐述:misconceptions around adding columns to a table.
推荐阅读
-
SQL Server误区30日谈 第28天 有关大容量事务日志恢复模式的误区
-
SQL Server误区30日谈 第30天 有关备份的30个误区
-
SQL Server误区30日谈 第29天 有关堆碎片的误区
-
SQL Server误区30日谈 第24天 26个有关还原(Restore)的误区
-
SQL Server误区30日谈 第17天 有关页校验和的误区
-
SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它
-
SQL Server误区30日谈 第23天 有关锁升级的误区
-
SQL Server误区30日谈 第6天 有关NULL位图的三个误区
-
SQL Server误区30日谈 第8天 有关对索引进行在线操作的误区