在Heap表中向页面输入行与8060字节的页面大小不匹配

Tom*_*rBu 3 sql sql-server

我正在编写一本书中的示例(考试70-461:查询Ben Gan的Microsoft SQL Server 2012),其中执行以下操作:

USE tempdb;
GO

CREATE TABLE TestTable
(
id INT NOT NULL,
col1 CHAR(36) NOT NULL,
col2 CHAR(216) NOT NULL --Each row is 256 bytes (int is 4 bytes long)
);
Run Code Online (Sandbox Code Playgroud)

请注意,根据列定义,每行应包含256个字节.

页面大小为8kb - > 8192字节.我们需要减去96bytes页面的Header大小以及36字节的行偏移数组.这使我们每页8060字节.

我的期望是页面将保持8060/256 = 31.5行.-> 31行.

让我们像这样插入30行:

DECLARE @i AS int = 1;
WHILE @i <= 30
BEGIN
    INSERT INTO dbo.TestTable
    (id, col1, col2)
    VALUES
    (@i, 'a', 'b');

    SET @i = @i + 1;
END;
Run Code Online (Sandbox Code Playgroud)

根据以下查询,所有数据仍包含在单个页面中:

SELECT index_type_desc, page_count,
       record_count,
       avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats (DB_ID(N'tempdb'),
                                    OBJECT_ID(N'dbo.TestTable'),
                                    NULL,
                                    NULL,
                                    'Detailed');
Run Code Online (Sandbox Code Playgroud)

这是输出:

index_type_desc page_count  record_count    avg_page_space_used_in_percent
HEAP                 1           30                98.1961947121324
Run Code Online (Sandbox Code Playgroud)

然后当我像这样插入31行时:

INSERT INTO dbo.TestTable
(id, col1, col2)
VALUES
(31, 'a', 'b');
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

index_type_desc page_count  record_count    avg_page_space_used_in_percent
HEAP                 2           31                50.7227575982209
Run Code Online (Sandbox Code Playgroud)

如果记录仍应保存在上一页中,为什么还要获取另一页?为了正确分析,我在这里缺少什么?

谢谢.

Lua*_*aan 5

每行还有一个标题.在您的情况下,这应该是8个字节.8060/264 = ~30.5,所以一页上只有30行:)

总而言之,对于每一行,您需要添加:

  • 2个字节的状态位
  • 固定数据长度为2个字节
  • 实际的固定数据(在你的情况下是256字节)
  • null-bitmap头的2个字节
  • 空位图标头(在您的情况下为0字节)
  • 2个字节用于可变数据列计数
  • 每个可变长度列偏移量为2个字节(在您的情况下为0个字节)
  • 实际的可变数据(在你的情况下为0字节)