我有一个有 483 列的表。
A date not null
、 a char(6) not null
,然后是 481 x float sparse null
。
根据我的数学计算,即使每个稀疏浮点都非空,该行仍然应该是:
date: 3 bytes
char(6): 6 bytes
sparse float: 12 bytes x 481
sparse update overhead: 2 bytes x 483
= 6747 bytes and way below the limit of 8060
(even allowing lots for other random overheads)
事实上,导致问题的实际行仍然有 133 个浮点列为空,并且 SQL Server 声称该行的行大小为 8108(并且太大)。
占据我行空间的幽灵是什么?
该表包含已删除的固定长度列。这可能作为数据转换的一部分或通过迭代开发发生,其中工具随着设计的发展修改现有的表结构。
正如 David Browne 指出的那样,这也可能是由于最初将(固定长度)
float
列创建为非稀疏 null ,然后将它们更改为稀疏列而发生的。这与文档相矛盾(强调是添加的):
事实上,重建结构并不是为了回收空间。
例子
将浮动列更改为稀疏:
使用未记录的系统视图显示删除的列:
为简洁起见,仅显示前十个条目:
使用除 133 个浮点列之外的所有值更新该行:
错误信息是:
要删除“幽灵”删除的固定长度列,您需要重建表:
之前的操作现在成功了。
db<>小提琴演示
固定长度的列不能用 清理
DBCC CLEANTABLE
。删除的可变长度列不会导致问题,因为在添加新的稀疏列时,SQL Server 可以清理它们或将它们移出行以腾出空间。