2019:
Slot 0, Offset 0x60, Length 4045, DumpStyle BYTE
2020:
Slot 0, Offset 0x60, Length 4047, DumpStyle BYTEnchar类型在存储的时候会+7 byte,,,
Slot 0, Offset 0x60, Length 4045, DumpStyle BYTE
2020:
Slot 0, Offset 0x60, Length 4047, DumpStyle BYTEnchar类型在存储的时候会+7 byte,,,
--2019大小
select 4047*2=8094
--2020大写
select 4049*2=8098为什么页的字节数是8096?不是说8060吗?..
这是3,再加行标题的4,就是7了
页头占了96Byte,剩下的就是存放数据和偏移量了,,,
-- 创建2个测试表
CREATE TABLE [dbo].[Table_2019]([Data] [nchar](2019) NOT NULL)
CREATE TABLE [dbo].[Table_2020]([Data] [nchar](2020) NOT NULL)
go
-- 填充数据
declare @i int
set @i = 0
while(@i < 20)
begin
insert Table_2019(Data) values('')
insert Table_2020(Data) values('')
select @i = @i + 1
end
go
exec sp_spaceused 'Table_2019'
go
exec sp_spaceused 'Table_2020' --结果:
Table_2019 20 200 KB 160 KB 8 KB 32 KB
Table_2020 20 200 KB 160 KB 8 KB 32 KB
--测试在tempdb库:
-- 创建2个测试表
CREATE TABLE [dbo].[Table_2019]([Data] [nchar](2019) NOT NULL)
CREATE TABLE [dbo].[Table_2020]([Data] [nchar](2020) NOT NULL)
go
-- 填充数据
declare @i int
set @i = 0
while(@i < 20)
begin
insert Table_2019(Data) values('')
insert Table_2020(Data) values('')
select @i = @i + 1
end
go
exec sp_spaceused 'Table_2019'
go
exec sp_spaceused 'Table_2020'
goTable_2019 20 136 KB 80 KB 8 KB 48 KB
Table_2020 20 200 KB 160 KB 8 KB 32 KB
仔细看联机帮助上的算法:保留行中称为空位图的部分以管理列的为空性。计算大小:
Null_Bitmap = 2 + ((Num_Cols + 7) / 8)只应使用该表达式的整数部分。而去掉其余部分。
22楼的测试,是在2005下吗,2000的master库计算是正常的。
3 -- 2 + ((总列数+ 7) / 8) = 2+ (1+7)/8 = 3
4 -- 是数据行的行标题开销
2 -- 是计算行数时引入的行大小余量
4047 * 2 = 8094 2020 * 2 + 3 + 4 + 2 = 4049
3 -- 2 + ((总列数+ 7) / 8) = 2+ (1+7)/8 = 3
4 -- 是数据行的行标题开销
2 -- 是计算行数时引入的行大小余量4049 * 2 = 8098 --->每页有 8096 可用字节--->
第一个一页可两行
第二个一页只能一行
是 Ceiling(总列数/8.),每一个 Bit 指示一个字段的 NULL BITMAP.一个Byte可以指示8个字段的null bitmap状态。
原来是为了实现?resutl = x%8==0? x/8 : 1+(x-x%8)/8
针对22楼的测试,我研究了一下,发现是Rowversing的原因造成的。在数据库打开"ALLOW_SNAPSHOT_ISOLATION" 选项后,为了做到rowversing,数据页中的每一行必须加上额外的14byte来跟踪行版本的指针。即行大小由原来的4047变成4061,一页只能存1行了。默认情况下,master & msdb两个库的ALLOW_SNAPSHOT_ISOLATION都是打开的。
--可以用这个查看每个库的rowversing是否打开
SELECT name,
snapshot_isolation_state_desc,
is_read_committed_snapshot_on , *
FROM sys.databases;
---验证方法:可以将AdventureWorks库打开ALLOW_SNAPSHOT_ISOLATION,在里面建Table_2019、 Table_2020,然后再看spaceused.ALTER DATABASE ADVENTUREWORKS SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
--测试在master库:
-- 创建2个测试表
CREATE TABLE [dbo].[Table_2019]([Data] [nchar](2019) NOT NULL)
CREATE TABLE [dbo].[Table_2020]([Data] [nchar](2020) NOT NULL)
go
-- 填充数据
declare @i int
set @i = 0
while(@i < 20)
begin
insert Table_2019(Data) values('')
insert Table_2020(Data) values('')
select @i = @i + 1
end
go
exec sp_spaceused 'Table_2019'
go
exec sp_spaceused 'Table_2020'
/*--结果:
Table_2019 20 200 KB 160 KB 8 KB 32 KB
Table_2020 20 200 KB 160 KB 8 KB 32 KB*/