要迁移到新架构,我要对表做两件事:
为了测试这会如何影响大小,我生成了180,000行。我正在更改的VARCHAR列在每一行都设置为null。
以下是sp_spaceused的结果(所有大小均以KB为单位):
Final_Mark
因此数据增长超过9MB。我原本预计它只会增长1.4 MB,因为我添加了一个8字节的数字列。
如果我只是创建表并生成数据,那么大小看起来更像我期望的那样:
rows reserved data index_size unused
---- -------- ---- ---------- ------
before 180000 110976 43168 67288 520
after 180000 120320 52536 67296 488
那么添加一个列会导致sp_spaceused报告使用的数据多于实际添加的数据吗?
答案 0 :(得分:1)
没有人真正解释为什么会这样。戴夫古格给了你一个很好的暗示。
SQL在页面中存储行。 (大概是8K,但不完全是)并且一行必须适合一个页面(不是真的,因为长的varchars可以使用指针存储在单独的页面上 - 但是你的全部都是null,所以我们暂时忽略它。)
页面以群集形式分配。
当您插入行时,您有一组很好的新页面和群集,并且行都很整洁。
在进行任何更改时,尤其是添加列时,SQL必须更新每一行。
更新任何行都需要更改一个或多个页面 - 因为更改的行可能不再适合同一页面。事实上,由于回滚的工作方式,我认为有时SQL实际上喜欢将更改的行移动到新页面。
因此,您紧密排列的行已分布并占用了更多页面和群集。随着时间的推移,有很多变化,这是平均值。并非每个更新都会添加页面 - 但添加列会使每一行变大,并且不太可能适合其先前的邻居。
我们不能更具体,因为您没有提供架构。如果有的话,我们会在您更改之前和之后了解每页的预期行数。
答案 1 :(得分:0)
正如大家所料,问题是分裂。生成数据并使用附加列迁移到新模式后,我使用sys.dm_db_index_physical_stats检查了碎片。聚集索引的avg_fragmentation_in_percent为98.8%。重建将其减少到0.4%,sp_spaceused显示数据大小从52MB减少到29MB。
感谢您提供的所有帮助。