Jon*_*des 18 sql-server-2008 disk-space
我有一个包含 490 M 行和 55 GB 表空间的表,所以每行大约 167 个字节。该表包含三列: a VARCHAR(100)、 aDATETIME2(0)和 a SMALLINT。VARCHAR字段中文本的平均长度约为 21.5,因此原始数据每行应约为 32 个字节: 22+2 表示VARCHAR, 6 表示DATETIME2,2 表示 16 位整数。
请注意,上面的空间仅是数据,而不是索引。我正在使用属性下报告的值 | 存储 | 一般 | 数据空间。
当然肯定会有一些开销,但是每行 135 个字节似乎很多,尤其是对于大表。为什么会这样?有没有其他人见过类似的乘数?哪些因素会影响所需的额外空间量?
为了进行比较,我尝试创建一个包含两个INT字段和 1 M 行的表。所需的数据空间为 16.4 MB:每行 17 个字节,而原始数据为 8 个字节。另一个测试表中的 anINT和 aVARCHAR(100)填充了与真实表相同的文本,每行使用 39 个字节(44 K 行),我预计 28 加上一点。
所以生产表有更多的开销。这是因为它更大吗?我希望索引大小大约为 N * log(N),但我不明白为什么实际数据所需的空间是非线性的。
在此先感谢您的指点!
编辑:
列出的所有字段都是NOT NULL. 真实的表在VARCHAR字段和DATETIME2字段上有一个聚集的 PK ,按这个顺序。对于这两个测试,第一个INT是(集群)PK。
如果重要:该表是 ping 结果的记录。这些字段是 URL、ping 日期/时间和以毫秒为单位的延迟。数据不断追加,从不更新,但数据会定期删除,以将其减少到每个 URL 每小时只有几条记录。
编辑:
这里一个非常有趣的答案表明,对于具有大量读写的索引,重建可能没有好处。就我而言,消耗的空间是一个问题,但如果写入性能更重要,那么使用松弛的索引可能会更好。
Mar*_*ith 11
经过对原问题的评论中的讨论,在这种情况下,丢失的空间似乎是由于选择了clustered key造成的,从而导致了大量碎片。
在这些情况下,始终值得通过 sys.dm_db_index_physical_stats 检查碎片状态。
编辑:在评论更新后
平均页面密度(在重建聚集索引之前)为 24%,这完全符合原始问题。这些页面只有 1/4 满,所以总大小是原始数据大小的 4 倍。
磁盘结构有开销:
取 2 x 4 字节 int 列,你有
哇 17 个字节!
您可以对第二个测试表进行相同的操作,它的开销与原始表一样:
为什么会有差异?另外(我不会链接到这些)
@updateusage = 'true'请参阅:SQL Server:如何创建一个填充 8 KB 页的表?
来自 SO: