sql-server-2008 – 为什么表的数据空间占用原始数据大小的4倍?

我有一个包含490 M行和55 GB表空间的表,因此每行大约167个字节.该表有三列:VARCHAR(100),DATETIME2(0)和SMALLINT. VARCHAR字段中文本的平均长度约为21.5,因此原始数据应为每行约32个字节:对于VARCHAR为22 2,对于DATETIME2为6,对于16位整数为2.

请注意,上面的空格只是数据,而不是索引.我正在使用Properties |下报告的值存储|一般|数据空间.

当然必须有一些开销,但每行135个字节似乎很多,特别是对于大型表.为什么会这样?还有其他人看过类似的乘数吗?哪些因素会影响所需的额外空间量?

为了比较,我尝试创建一个包含两个INT字段和1M行的表.所需的数据空间为16.4 MB:每行17个字节,而原始数据为8个字节.另一个带有INT和VARCHAR(100)的测试表填充了与真实表相同的文本,每行使用39个字节(44 K行),我希望28加一点.

因此生产表有更多的开销.这是因为它更大吗?我希望索引大小大致为N * log(N),但我不明白为什么实际数据所需的空间是非线性的.

提前感谢任何指针!

编辑:

列出的所有字段都不是NULL.真实表在VARCHAR字段和DATETIME2字段上按顺序具有聚簇PK.对于这两个测试,第一个INT是(聚集的)PK.

如果重要:该表是ping结果的记录.字段是URL,ping日期/时间和延迟(以毫秒为单位).数据会不断附加,并且永远不会更新,但会定期删除数据,以便将每个URL的每小时数量减少到几个记录.

编辑:

一个非常有趣的答案here表明,对于具有大量阅读和写作的索引,重建可能没有益处.在我的情况下,消耗的空间是一个问题,但如果写入性能更重要,那么使用松弛的索引可能会更好.

解决方法

在对原始问题的评论中进行讨论之后,在这种情况下看来,丢失的空间是由群集密钥的选择引起的,这导致了大量的碎片化.

在这些情况下,始终值得通过sys.dm_db_index_physical_stats检查碎片状态.

编辑:在评论中更新

平均页面密度(在重建聚集索引之前)为24%,这与原始问题完全吻合.页面只有1/4满,因此总大小是原始数据大小的4倍.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...