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

Sca*_*bas 1 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)
);
Run Code Online (Sandbox Code Playgroud)

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

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

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

编辑:我应该提到这个表已被更改,使用更改跟踪并有四个索引.

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

The*_*rst 5

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

ALTER TABLE dbo.MyTable disable change_tracking
ALTER TABLE dbo.MyTable enable change_tracking
Run Code Online (Sandbox Code Playgroud)

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

要检查这一点,请system_internals_partition_columns查看视图,看看是否有大量的列is_dropped.有许多原因可能有更多原因,但这种使用变更跟踪的方式就是其中之一.

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

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