SQL Server 2012 中的最大行大小与 varchar(max) 字段

Posted

技术标签:

【中文标题】SQL Server 2012 中的最大行大小与 varchar(max) 字段【英文标题】:Max Row Size in SQL Server 2012 with varchar(max) fields 【发布时间】:2013-10-08 14:48:56 【问题描述】:

我创建了一个列类型为nvarchar(max) 的表,我的理解是它们可以支持2GB。但是在插入时,我仍然收到此错误:

无法创建大于允许的最大行大小 8060 的大小为 8061 的行。

是否需要对数据库进行全局设置,或者我是否还有其他限制?每个表的varchar(max) 字段数量是否有限制?

【问题讨论】:

向我们展示您实际执行的 SQL 代码。表定义也会很有帮助。 您有多少个[n]varchar(max) 列?即使实际数据存储在行外,行本身仍然需要一个指向它的指针,因此如果您要为数百个可变宽度列插入值,您可以仅在指针上用完空间。有时也会出现此错误,因为删除/更改的固定宽度列仍然占用空间。 有几百列。我没有任何数据,第一次插入失败。 @MartinSmith 我认为您正在使用指针进行操作。如果我使用 varchar(max) 而不是 nvarchar(max) 创建表,它似乎工作正常。谢谢 完全没有代码:没有表定义,没有插入语句。 【参考方案1】:

SQL 服务器使用页面来存储数据。页面大小为 8kb。

所以 SQL server 中的记录大小(行大小)不能大于 8060 字节。

如果数据不适合 8060 字节,则使用引用指针。 当 varchar、nvarchar、varbinary、sql_variant 或 CLR 用户定义类型列的组合超过此限制时,SQL Server 数据库引擎将具有最大宽度的记录列移动到 ROW_OVERFLOW_DATA 分配单元中的另一个页面,同时保持 原始页面上的 24 字节指针

将大记录移动到另一个页面是动态发生的,因为记录会根据更新操作而延长。缩短记录的更新操作可能会导致记录移回 IN_ROW_DATA 分配单元中的原始页面。

此外,查询和执行其他选择操作(例如对包含行溢出数据的大型记录进行排序或连接)会减慢处理时间,因为这些记录是同步处理的,而不是异步处理的。

使用稀疏列的表的记录大小限制为 8,018 字节。当转换后的数据加上已有记录数据超过 8018 字节时,返回 MSSQLSERVER ERROR 576。在稀疏类型和非稀疏类型之间转换列时,数据库引擎会保留当前记录数据的副本。这会暂时使记录所需的存储空间增加一倍。 .

要获取有关可能包含行溢出数据的表或索引的信息,请使用 sys.dm_db_index_physical_stats 动态管理函数。

【讨论】:

【参考方案2】:

来自 SQL Server 文档:

各列的长度仍必须在 varchar、nvarchar、varbinary、sql_variant 和 CLR 为 8,000 字节 用户定义的类型列。 只有它们的组合长度才能超过 表的行数限制为 8,060 字节。

其他数据类型列的总和,包括char和nchar数据, 必须在 8,060 字节的行限制内。大对象数据也是 免除 8,060 字节的行限制。

更多信息在这里:https://technet.microsoft.com/en-us/library/ms186981%28v=sql.105%29.aspx

【讨论】:

【参考方案3】:

这来自 *** 上的较早线程,可在此处找到:

Cannot create a row of size 8937 which is greater than the allowable maximum of 8060

该错误是因为 SQL Server 中的行不能大于 8KB(一页大小),因为行不允许跨页 - 这是 SQL Server 的基本限制 [...]

请注意,SQL Server 将允许您创建表,但是如果您尝试实际插入跨越多个页面的任何数据,则会出现上述错误。 当然,这并没有完全加起来,因为如果以上是全部事实,那么单个 VARCHAR(8000) 列将填充表中的一行! (这曾经是这种情况)。 SQL Server 2005 通过允许将一行中的某些数据存储在另一页中,而不是保留一个 24 位指针来解决此限制。

我建议将您的表格规范化为一个或多个相关表格。

【讨论】:

以上是关于SQL Server 2012 中的最大行大小与 varchar(max) 字段的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver log数据库设置最大文件大小为啥固定的2,097,152

根据sql server 2012中后续行索引之间的差异创建分区

如何面对 SQL Server Express 2008 中的数据库限制问题?

将 SQL Server 中的字符串拆分为最大长度,并将每个字符串作为一行返回

SQL Server 2012 Express 如何从一列中提取信息并将其与具有表达式限制的另一列进行比较

SQL Server Management Studio 中的脚本大小限制