如果启用“行外大值类型”表选项,则表大小会增加

got*_*tqn 3 t-sql sql-server-2012

我最近了解了sp_tableoption,它使您能够为特定表存储“行外大值类型”。

我的一个同事告诉我,如果我启用它,每个字段至少存储在 8 KB 页面上,无论它有多大。我无法找到对此的确认,因此我运行了以下测试:

DROP TABLE Size

CREATE TABLE Size
(
    [ID] TINYINT
   ,[Text] NVARCHAR(MAX)
)


EXEC sp_tableoption 'Size' ,'large value types out of row' ,0

TRUNCATE TABLE Size

INSERT INTO Size
SELECT 1, N'in row text'
UNION ALL
SELECT 2, N'' -- add here very large string

SELECT [ID], DATALENGTH([Text]) Size, LEN([Text]) [Len]
FROM [dbo].[Size]

EXEC sp_spaceused Size;


DROP TABLE Size

CREATE TABLE Size
(
    [ID] TINYINT
   ,[Text] NVARCHAR(MAX)
)

EXEC sp_tableoption 'Size' ,'large value types out of row' ,1


TRUNCATE TABLE Size

INSERT INTO Size
SELECT 1, N'in row text'
UNION ALL
SELECT 2,  N'' -- add here very large string


SELECT [ID], DATALENGTH([Text]) Size, LEN([Text]) [Len]
FROM [dbo].[Size]

EXEC sp_spaceused Size;
Run Code Online (Sandbox Code Playgroud)

并得到以下结果:

在此处输入图片说明

因此,似乎第一行现在占用了更多空间(正好是 8 KB)。因此,我再添加一行并再次进行测试:

INSERT INTO Size
SELECT 1, N'in row text'
UNION ALL
SELECT 1, N'in row text'
UNION ALL
SELECT 2,  N'' -- add here very large string
Run Code Online (Sandbox Code Playgroud)

结果是一样的。因此,每行至少占用 8 KB 是不正确的,但实际上增加了大小。我知道:

表中的 varchar(max)、nvarchar(max)、varbinary(max)、xml 和大型用户定义类型 (UDT) 列存储在行外,具有指向根的 16 字节指针。

但是在这种情况下可以忽略这个 16 字节的指针。

small如果选项为真,谁能告诉有没有办法确定将花费多少空间开销值?

我打算将此选项应用于大表并想计算表大小将如何受到影响。

请注意,我知道该值仅out of the row在插入或更新时才会移动。

小智 5

如果你使用

DBCC IND('TestDb', 'Size', -1)
Run Code Online (Sandbox Code Playgroud)

您可以获得 LOB 页面的文件和页码(其中保存了“行外”值) 指数和 IAM 现在,使用该信息获取页面的转储:

DBCC PAGE('TestDb', 3, 938947, 1) WITH TABLERESULTS;
Run Code Online (Sandbox Code Playgroud)

BLOB 开销

从这些结果我可以看到,对于 64 字节或更少的字符串,记录大小将始终为 84 字节。对于更长的字符串将是实际字节加上 14 个字节(我没有分析比页面长的字符串)并且存储引擎将尝试在 LOB 页面中容纳尽可能多的这些记录。