我在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?
编辑:我应该提一下,此表已被更改,使用更改跟踪并有四个索引。
此外,如果我将内容复制到具有相同定义的新表,一段时间内不会发生错误,但确实会回来。
答案 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-hood):他列出的查询应该是你需要看到的,如果是上述情况。
修改强>
如果您需要删除已删除的列,则可以为具有许多已删除列的表重建聚簇索引。这意味着重建MyTable
的聚集索引可以减轻您的症状。