为什么我的行大小超过允许的最大值8060字节

时间:2017-08-15 13:46:29

标签: sql sql-server

我在SQL Server 2012,Web Edition中有以下表格:

CREATE TABLE [dbo].[MyTable] 
(
     [Id]               INT            IDENTITY (1, 1) NOT NULL,
     [Created]          DATETIME       DEFAULT (getdate()) NOT NULL,
     [RefId]            INT            NULL,
     [Name]             NVARCHAR (128) NULL,
     [Email]            NVARCHAR (128) NULL,
     [ImageUrl]         NVARCHAR (256) NULL,
     [Url]              VARCHAR (256)  NULL,
     [Age]              TINYINT        NULL,
     [Country]          VARCHAR (6)    NULL,
     [Location]         NVARCHAR (192) NULL,
     [People]           INT            NULL,
     [Categories]       NVARCHAR (128) NULL,
     [Block]            BIT            DEFAULT ((0)) NOT NULL,
     [GeneratedRevenue] INT            NULL,
     [IsFemale]         BIT            DEFAULT ((1)) NULL,
     [HasInstalled]     BIT            NULL,
     [Keywords]         VARCHAR (128)  NULL,
     [Brands]           NVARCHAR (512) NULL,
     [Source]           TINYINT        NULL,
     [Alias]            VARCHAR (65)   NULL,

     PRIMARY KEY CLUSTERED ([Id] ASC)
);

据我所知,总大小应为3175字节;但是在更新表时我经常会收到以下错误:

  

无法创建大小为8068的行,该行大于允许的最大行大小8060.

上述结果如何导致行大小为8068?

编辑:我应该提一下,此表已被更改,使用更改跟踪并有四个索引。

此外,如果我将内容复制到具有相同定义的新表,一段时间内不会发生错误,但确实会回来。

1 个答案:

答案 0 :(得分:5)

您说您使用更改跟踪。您是否 - 无论如何 - 忽略变更跟踪的版本控制部分,并通过执行以下操作重置条目?

ALTER TABLE dbo.MyTable disable change_tracking
ALTER TABLE dbo.MyTable enable change_tracking

如果是这样,您可能有嫌犯。每次重新启用更改跟踪时,更改跟踪会在后台添加一个8位列,如果已经存在,则会删除该列。由于删除列只是一个元操作,因此您可能会在幕后隐藏大量丢弃的8位列,具体取决于您重新启用更改跟踪的频率。

要检查此问题,请查看system_internals_partition_columns视图,看看您是否有大量is_dropped列。可能有更多理由可以使用其中许多,但这种使用变更跟踪的方式就是其中之一。

我看到Remus Rusanu链接到评论中的一篇好文章(rusanu.com/2011/10/20/sql-server-table-columns-under-the-hoo‌​d):他列出的查询应该是你需要看到的,如果是上述情况。

修改 如果您需要删除已删除的列,则可以为具有许多已删除列的表重建聚簇索引。这意味着重建MyTable的聚集索引可以减轻您的症状。