8Kb 行大小限制被忽略 - 但只是有时!

Mou*_*ark 3 sql-server-2012 varbinary

由于代码测试不佳(不是我的!),我最终得到了一个包含 319 个VARBINARY(MAX)字段、两个DATETIME字段和两个UNIQUEIDENTIFIER字段的表。显然这并不理想,但它应该仍然在 SQL Server 可以处理的行大小的限制内。

据我了解,VARBINARY(MAX)它作为一个 24 字节的指针存储在表上,指向行外存储。24 * 319 = 7656字节,加上其他四个字段= 7704个字节,所以我只是在我可以投入一排的限制。

这一切都很好,直到代码开始将数据插入到这个表中。在与消息崩溃之前它有 6 行:

无法创建大小为 8345 的行,该行大于允许的最大行大小 8060。语句已终止。

这是非常令人费解的,因为任何行都不应该比其他行大(至少在行上)。我已经编写了表格的脚本,它看起来不错。我确实注意到它是用创建的,ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]尽管我不确定会产生什么效果。

有谁知道这里可能会发生什么,更重要的是我如何解决它?

这是用于创建数据库的代码,以及插入命令

CREATE DATABASE MyBigDB;
GO
USE [MyBigDB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Autogenerated table with really big data](
    [Primary_key] [uniqueidentifier] NULL,
    [A Foreign key] [uniqueidentifier] NULL,
    [Created] [datetime] NULL,
    [Updated] [datetime] NULL,
    [c1] [varbinary](max) NULL,
    [c2] [varbinary](max) NULL,
    [c3] [varbinary](max) NULL,
    [c4] [varbinary](max) NULL,
    ...
    ...
    etc
    ...
    ...
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

INSERT INTO [Autogenerated table with really big data] ([Primary_key], [A Foreign key], [Created], [Updated], [c1], [c2], [c3], [c4],............)
VALUES (<a UID>, <a UID>, <a DATETIME>, <a DATETIME>, <binary blob>, <binary blob>,............)
Run Code Online (Sandbox Code Playgroud)

oou*_*ire 6

SQL 版本

Microsoft SQL Server 2012 - 11.0.5343.0 (X64)

回应

指向 LOB_DATA 页的指针(您的 24 字节指针)仅在包含 VARBINARY(MAX) 列的行不再适合该页时使用。

我仍在努力匹配您上面提到的确切场景。

参考资料

槽阵列和总页面大小

使用 [大师];
走

如果 DATABASEPROPERTYEX (N'RowSize', N'Version') > 0
开始
    ALTER DATABASE [RowSize] SET SINGLE_USER
        立即回滚;
    删除数据库 [行大小];
结尾;
走

创建数据库 [RowSize];
走

使用 [行大小];
走

如果 OBJECT_ID('test' , 'U') 不是 NULL
开始
     删除表 dbo.test;
结尾;

-- 创建宽表
创建表 dbo.test
(
      c1 唯一标识符 NULL
    , c2 唯一标识符 NULL
    , c3 日期时间 NULL
    , c4 日期时间 NULL
    , c5 VARBINARY(MAX) NULL
    , c6 VARBINARY(MAX) NULL
    , c7 VARBINARY(MAX) NULL
    , c8 VARBINARY(MAX) NULL
    , c9 VARBINARY(MAX) NULL
    , c10 VARBINARY(MAX) NULL
    , c11 VARBINARY(MAX) NULL
    , c12 VARBINARY(MAX) NULL
    , c13 VARBINARY(MAX) NULL
    , c14 VARBINARY(MAX) NULL
    , c15 VARBINARY(MAX) NULL
    , c16 VARBINARY(MAX) NULL
    , c17 VARBINARY(MAX) NULL
    , c18 VARBINARY(MAX) NULL
    , c19 VARBINARY(MAX) NULL
    , c20 VARBINARY(MAX) NULL
    , c21 VARBINARY(MAX) NULL
    , c22 VARBINARY(MAX) NULL
    , c23 VARBINARY(MAX) NULL
    , c24 VARBINARY(MAX) NULL
    , c25 VARBINARY(MAX) NULL
    , c26 VARBINARY(MAX) NULL
    , c27 VARBINARY(MAX) NULL
    , c28 VARBINARY(MAX) NULL
    , c29 VARBINARY(MAX) NULL
    , c30 VARBINARY(MAX) NULL
    , c31 VARBINARY(MAX) NULL
    , c32 VARBINARY(MAX) NULL
    , c33 VARBINARY(MAX) NULL
    , c34 VARBINARY(MAX) NULL
    , c35 VARBINARY(MAX) NULL
    , c36 VARBINARY(MAX) NULL
    , c37 VARBINARY(MAX) NULL
    , c38 VARBINARY(MAX) NULL
    , c39 VARBINARY(MAX) NULL
    , c40 VARBINARY(MAX) NULL
    , c41 VARBINARY(MAX) NULL
    , c42 VARBINARY(MAX) NULL
    , c43 VARBINARY(MAX) NULL
    , c44 VARBINARY(MAX) NULL
    , c45 VARBINARY(MAX) NULL
    , c46 VARBINARY(MAX) NULL
    , c47 VARBINARY(MAX) NULL
    , c48 VARBINARY(MAX) NULL
    , c49 VARBINARY(MAX) NULL
    , c50 VARBINARY(MAX) NULL
    , c51 VARBINARY(MAX) NULL
    , c52 VARBINARY(MAX) NULL
    , c53 VARBINARY(MAX) NULL
    , c54 VARBINARY(MAX) NULL
    , c55 VARBINARY(MAX) NULL
    , c56 VARBINARY(MAX) NULL
    , c57 VARBINARY(MAX) NULL
    , c58 VARBINARY(MAX) NULL
    , c59 VARBINARY(MAX) NULL
    , c60 VARBINARY(MAX) NULL
    , c61 VARBINARY(MAX) NULL
    , c62 VARBINARY(MAX) NULL
    , c63 VARBINARY(MAX) NULL
    , c64 VARBINARY(MAX) NULL
    , c65 VARBINARY(MAX) NULL
    , c66 VARBINARY(MAX) NULL
    , c67 VARBINARY(MAX) NULL
    , c68 VARBINARY(MAX) NULL
    , c69 VARBINARY(MAX) NULL
    , c70 VARBINARY(MAX) NULL
    , c71 VARBINARY(MAX) NULL
    , c72 VARBINARY(MAX) NULL
    , c73 VARBINARY(MAX) NULL
    , c74 VARBINARY(MAX) NULL
    , c75 VARBINARY(MAX) NULL
    , c76 VARBINARY(MAX) NULL
    , c77 VARBINARY(MAX) NULL
    , c78 VARBINARY(MAX) NULL
    , c79 VARBINARY(MAX) NULL
    , c80 VARBINARY(MAX) NULL
    , c81 VARBINARY(MAX) NULL
    , c82 VARBINARY(MAX) NULL
    , c83 VARBINARY(MAX) NULL
    , c84 VARBINARY(MAX) NULL
    , c85 VARBINARY(MAX) NULL
    , c86 VARBINARY(MAX) NULL
    , c87 VARBINARY(MAX) NULL
    , c88 VARBINARY(MAX) NULL
    , c89 VARBINARY(MAX) NULL
    , c90 VARBINARY(MAX) NULL
    , c91 VARBINARY(MAX) NULL
    , c92 VARBINARY(MAX) NULL
    , c93 VARBINARY(MAX) NULL
    , c94 VARBINARY(MAX) NULL
    , c95 VARBINARY(MAX) NULL
    , c96 VARBINARY(MAX) NULL
    , c97 VARBINARY(MAX) NULL
    , c98 VARBINARY(MAX) NULL
    , c99 VARBINARY(MAX) NULL
    , c100 VARBINARY(MAX) NULL
    , c101 VARBINARY(MAX) NULL
    , c102 VARBINARY(MAX) NULL
    , c103 VARBINARY(MAX) NULL
    , c104 VARBINARY(MAX) NULL
    , c105 VARBINARY(MAX) NULL
    , c106 VARBINARY(MAX) NULL
    , c107 VARBINARY(MAX) NULL
    , c108 VARBINARY(MAX) NULL
    , c109 VARBINARY(MAX) NULL
    , c110 VARBINARY(MAX) NULL
    , c111 VARBINARY(MAX) NULL
    , c112 VARBINARY(MAX) NULL
    , c113 VARBINARY(MAX) NULL
    , c114 VARBINARY(MAX) NULL
    , c115 VARBINARY(MAX) NULL
    , c116 VARBINARY(MAX) NULL
    , c117 VARBINARY(MAX) NULL
    , c118 VARBINARY(MAX) NULL
    , c119 VARBINARY(MAX) NULL
    , c120 VARBINARY(MAX) NULL
    , c121 VARBINARY(MAX) NULL
    , c122 VARBINARY(MAX) NULL
    , c123 VARBINARY(MAX) NULL
    , c124 VARBINARY(MAX) NULL
    , c125 VARBINARY(MAX) NULL
    , c126 VARBINARY(MAX) NULL
    , c127 VARBINARY(MAX) NULL
    , c128 VARBINARY(MAX) NULL
    , c129 VARBINARY(MAX) NULL
    , c130 VARBINARY(MAX) NULL
    , c131 VARBINARY(MAX) NULL
    , c132 VARBINARY(MAX) NULL
    , c133 VARBINARY(MAX) NULL
    , c134 VARBINARY(MAX) NULL
    , c135 VARBINARY(MAX) NULL
    , c136 VARBINARY(MAX) NULL
    , c137 VARBINARY(MAX) NULL
    , c138 VARBINARY(MAX) NULL
    , c139 VARBINARY(MAX) NULL
    , c140 VARBINARY(MAX) NULL
    , c141 VARBINARY(MAX) NULL
    , c142 VARBINARY(MAX) NULL
    , c143 VARBINARY(MAX) NULL
    , c144 VARBINARY(MAX) NULL
    , c145 VARBINARY(MAX) NULL
    , c146 VARBINARY(MAX) NULL
    , c147 VARBINARY(MAX) NULL
    , c148 VARBINARY(MAX) NULL
    , c149 VARBINARY(MAX) NULL
    , c150 VARBINARY(MAX) NULL
    , c151 VARBINARY(MAX) NULL
    , c152 VARBINARY(MAX) NULL
    , c153 VARBINARY(MAX) NULL
    , c154 VARBINARY(MAX) NULL
    , c155 VARBINARY(MAX) NULL
    , c156 VARBINARY(MAX) NULL
    , c157 VARBINARY(MAX) NULL
    , c158 VARBINARY(MAX) NULL
    , c159 VARBINARY(MAX) NULL
    , c160 VARBINARY(MAX) NULL
    , c161 VARBINARY(MAX) NULL
    , c162 VARBINARY(MAX) NULL
    , c163 VARBINARY(MAX) NULL
    , c164 VARBINARY(MAX) NULL
    , c165 VARBINARY(MAX) NULL
    , c166 VARBINARY(MAX) NULL
    , c167 VARBINARY(MAX) NULL
    , c168 VARBINARY(MAX) NULL
    , c169 VARBINARY(MAX) NULL
    , c170 VARBINARY(MAX) NULL
    , c171 VARBINARY(MAX) NULL
    , c172 VARBINARY(MAX) NULL
    , c173 VARBINARY(MAX) NULL
    , c174 VARBINARY(MAX) NULL
    , c175 VARBINARY(MAX) NULL
    , c176 VARBINARY(MAX) NULL
    , c177 VARBINARY(MAX) NULL
    , c178 VARBINARY(MAX) NULL
    , c179 VARBINARY(MAX) NULL
    , c180 VARBINARY(MAX) NULL
    , c181 VARBINARY(MAX) NULL
    , c182 VARBINARY(MAX) NULL
    , c183 VARBINARY(MAX) NULL
    , c184 VARBINARY(MAX) NULL
    , c185 VARBINARY(MAX) NULL
    , c186 VARBINARY(MAX) NULL
    , c187 VARBINARY(MAX) NULL
    , c188 VARBINARY(MAX) NULL
    , c189 VARBINARY(MAX) NULL
    , c190 VARBINARY(MAX) NULL
    , c191 VARBINARY(MAX) NULL
    , c192 VARBINARY(MAX) NULL
    , c193 VARBINARY(MAX) NULL
    , c194 VARBINARY(MAX) NULL
    , c195 VARBINARY(MAX) NULL
    , c196 VARBINARY(MAX) NULL
    , c197 VARBINARY(MAX) NULL
    , c198 VARBINARY(MAX) NULL
    , c199 VARBINARY(MAX) NULL
    , c200 VARBINARY(MAX) NULL
    , c201 VARBINARY(MAX) NULL
    , c202 VARBINARY(MAX) NULL
    , c203 VARBINARY(MAX) NULL
    , c204 VARBINARY(MAX) NULL
    , c205 VARBINARY(MAX) NULL
    , c206 VARBINARY(MAX) NULL
    , c207 VARBINARY(MAX) NULL
    , c208 VARBINARY(MAX) NULL
    , c209 VARBINARY(MAX) NULL
    , c210 VARBINARY(MAX) NULL
    , c211 VARBINARY(MAX) NULL
    , c212 VARBINARY(MAX) NULL
    , c213 VARBINARY(MAX) NULL
    , c214 VARBINARY(MAX) NULL
    , c215 VARBINARY(MAX) NULL
    , c216 VARBINARY(MAX) NULL
    , c217 VARBINARY(MAX) NULL
    , c218 VARBINARY(MAX) NULL
    , c219 VARBINARY(MAX) NULL
    , c220 VARBINARY(MAX) NULL
    , c221 VARBINARY(MAX) NULL
    , c222 VARBINARY(MAX) NULL
    , c223 VARBINARY(MAX) NULL
    , c224 VARBINARY(MAX) NULL
    , c225 VARBINARY(MAX) NULL
    , c226 VARBINARY(MAX) NULL
    , c227 VARBINARY(MAX) NULL
    , c228 VARBINARY(MAX) NULL
    , c229 VARBINARY(MAX) NULL
    , c230 VARBINARY(MAX) NULL
    , c231 VARBINARY(MAX) NULL
    , c232 VARBINARY(MAX) NULL
    , c233 VARBINARY(MAX) NULL
    , c234 VARBINARY(MAX) NULL
    , c235 VARBINARY(MAX) NULL
    , c236 VARBINARY(MAX) NULL
    , c237 VARBINARY(MAX) NULL
    , c238 VARBINARY(MAX) NULL
    , c239 VARBINARY(MAX) NULL
    , c240 VARBINARY(MAX) NULL
    , c241 VARBINARY(MAX) NULL
    , c242 VARBINARY(MAX) NULL
    , c243 VARBINARY(MAX) NULL
    , c244 VARBINARY(MAX) NULL
    , c245 VARBINARY(MAX) NULL
    , c246 VARBINARY(MAX) NULL
    , c247 VARBINARY(MAX) NULL
    , c248 VARBINARY(MAX) NULL
    , c249 VARBINARY(MAX) NULL
    , c250 VARBINARY(MAX) NULL
    , c251 VARBINARY(MAX) NULL
    , c252 VARBINARY(MAX) NULL
    , c253 VARBINARY(MAX) NULL
    , c254 VARBINARY(MAX) NULL
    , c255 VARBINARY(MAX) NULL
    , c256 VARBINARY(MAX) NULL
    , c257 VARBINARY(MAX) NULL
    , c258 VARBINARY(MAX) NULL
    , c259 VARBINARY(MAX) NULL
    , c260 VARBINARY(MAX) NULL
    , c261 VARBINARY(MAX) NULL
    , c262 VARBINARY(MAX) NULL
    , c263 VARBINARY(MAX) NULL
    , c264 VARBINARY(MAX) NULL
    , c265 VARBINARY(MAX) NULL
    , c266 VARBINARY(MAX) NULL
    , c267 VARBINARY(MAX) NULL
    , c268 VARBINARY(MAX) NULL
    , c269 VARBINARY(MAX) NULL
    , c270 VARBINARY(MAX) NULL
    , c271 VARBINARY(MAX) NULL
    , c272 VARBINARY(MAX) NULL
    , c273 VARBINARY(MAX) NULL
    , c274 VARBINARY(MAX) NULL
    , c275 VARBINARY(MAX) NULL
    , c276 VARBINARY(MAX) NULL
    , c277 VARBINARY(MAX) NULL
    , c278 VARBINARY(MAX) NULL
    , c279 VARBINARY(MAX) NULL
    , c280 VARBINARY(MAX) NULL
    , c281 VARBINARY(MAX) NULL
    , c282 VARBINARY(MAX) NULL
    , c283 VARBINARY(MAX) NULL
    , c284 VARBINARY(MAX) NULL
    , c285 VARBINARY(MAX) NULL
    , c286 VARBINARY(MAX) NULL
    , c287 VARBINARY(MAX) NULL
    , c288 VARBINARY(MAX) NULL
    , c289 VARBINARY(MAX) NULL
    , c290 VARBINARY(MAX) NULL
    , c291 VARBINARY(MAX) NULL
    , c292 VARBINARY(MAX) NULL
    , c293 VARBINARY(MAX) NULL
    , c294 VARBINARY(MAX) NULL
    , c295 VARBINARY(MAX) NULL
    , c296 VARBINARY(MAX) NULL
    , c297 VARBINARY(MAX) NULL
    , c298 VARBINARY(MAX) NULL
    , c299 VARBINARY(MAX) NULL
    , c300 VARBINARY(MAX) NULL
    , c301 VARBINARY(MAX) NULL
    , c302 VARBINARY(MAX) NULL
    , c303 VARBINARY(MAX) NULL
    , c304 VARBINARY(MAX) NULL
    , c305 VARBINARY(MAX) NULL
    , c306 VARBINARY(MAX) NULL
    , c307 VARBINARY(MAX) NULL
    , c308 VARBINARY(MAX) NULL
    , c309 VARBINARY(MAX) NULL
    , c310 VARBINARY(MAX) NULL
    , c311 VARBINARY(MAX) NULL
    , c312 VARBINARY(MAX) NULL
    , c313 VARBINARY(MAX) NULL
    , c314 VARBINARY(MAX) NULL
    , c315 VARBINARY(MAX) NULL
    , c316 VARBINARY(MAX) NULL
    , c317 VARBINARY(MAX) NULL
    , c318 VARBINARY(MAX) NULL
    , c319 VARBINARY(MAX) NULL
    , c320 VARBINARY(MAX) NULL
    , c321 VARBINARY(MAX) NULL
    , c322 VARBINARY(MAX) NULL
    , c323 VARBINARY(MAX) NULL
);
走
/* 我收到这个警告...

警告:表“test”已创建,但其最大行大小超过了允许的最大值 8060 字节。 
如果结果行超过大小限制,则对该表的 INSERT 或 UPDATE 将失败。

*/

-- 创建一行
插入 dbo.test (c1, c2, c3, c4)
    值 (NEWID() , NEWID() , GETDATE() , GETDATE());

——在吗?
选择 * 从 dbo.test;
走


——多少页?
DBCC IND (RowSize,test,-1); -- 我们有 IAM 页面和单个数据页面
GO -- 请注意,此时该行存储为 IN_ROW_DATA。
DBCC TRACEON(3604);
走
DBCC 页面 (RowSize, 1, 283, 3);
走

/*
m_freeCnt = 7999
10003400 c203754c 9b36f44b 8dafee3b b32bd7c6
3106ac3a 8ec6854e b68291e6 4ccf7872 b321e100
f2a40000 b321e100 f2a40000 4301f0ff ffffffff
ffffffff ffffffff ffffffff ffffffff ffffffff
ffffffff ffffffff ffffffff ffff07

标签 A:0x10
标签 B:0x00
空位图偏移:0x0034 = 52 dec。
GUID 1:c203754c 9b36f44b 8dafee3b b32bd7c6
GUID 2:3106ac3a 8ec6854e b68291e6 4ccf7872 
日期时间 1:b321e100 f2a40000
日期时间 2:b321e100 f2a40000
列数:0x0143 = 12 月 323 日。
空位图:0xc0fff...

可变长度列数
+ 可变长度列偏移数组 
+ 可变长度列:目前不存在    
   
总开销: 
    标签 A:1B
    标签 B:1B
    空位图偏移:2B
    列数:2B
    空位图:41B
    页眉:96B
    插槽阵列:2B = 145B 

行的固定大小: 
    (16 + 16 + 8 + 8)B = 48B

总使用字节数:145B + 48B = 193B = 8192B [8K 页] - 7999B [m_freeCnt]

********************************
注意:没有存储指针。此时该行存储为 IN_ROW_DATA。
********************************
*/

-- 更新一行
更新 dbo.test
SET c5 = CONVERT(VARBINARY(MAX), REPLICATE(0x11, 7961));
走

-- m_freeCnt 现在是什么?
-- m_freeCnt = 34

——多少页?
DBCC IND (RowSize,test,-1); -- 我们有 IAM 页面和单个数据页面
走
DBCC 页面 (RowSize, 1, 283, 3);
走

/*

当开启并使用快照隔离时,可以使 m_freeCnt 等于 20,
但它不能低于那个,因为剩余的字节是 
保留供 SQL Server 团队将来使用


可变长度列数:0x0001 (2B)
可变长度列偏移数组:0x157c (2B) 
可变长度列:0x11111111...


*/

-- 更新一行
更新 dbo.test
SET c5 = CONVERT(VARBINARY(MAX), REPLICATE(0x11, 7962));
走

——多少页?
DBCC IND (RowSize,test,-1); -- 我们有 2 个 IAM 页,一个 IN_ROW_DATA 页和一个 LOB_DATA 页
走
DBCC 页面 (RowSize, 1, 283, 3);
走

/*

您的 24 字节指针位于第 283 页(IN_ROW_DATA 页)

*/

  • @Mourndark 是的,您将数据添加到更多列并最终获得 LOB 分配单元。有这么多列,您几乎会立即填满该行;这就是为什么不推荐创建如此宽的表的原因之一。最后,这张表实际上并没有定义任何实体,也不是一个很好的临时表设计。您可能需要考虑使用 FILESTREAM 或其他一些方法来将您的 blob 保存到数据库之外。 (2认同)
  • 很好的解释,+1。此外,我创建了一个测试来帮助澄清这种行为的细节,因为不清楚@Mourndark 如何解释这些信息。这个问题没有上限,所以最好说如果所有字段 &gt;= 24,那么它就失败了。如果某些字段为 NULL 或 &lt; 24 字节,当然会有变化。你可以在这里看到测试:http://pastebin.com/2gD6eqkd (2认同)