为什么更改数据类型不会影响数据库大小?

Flo*_*ian 5 sql-server datatypes sql-server-2016

我有一个包含四列和约 6.6 亿行的表格。其中两列是 bigint,尽管它们实际上并不需要包含任何不能放入 int 的内容。因此作为测试,我将它们的数据类型从 bigint 更改为 int。该表上有一个聚集索引,它的键不使用这两列。

结果令我困惑。数据空间(在表属性中)保持不变,而索引空间下降了 23.5%。有人可以向我解释那里发生了什么吗?为什么数据空间没有改变?

顺便说一句,我做了类似于另一张桌子的事情。那里的数据空间下降了 30.4%,这正是我根据行大小的变化计算得出的。索引空间的下降类似。

[编辑说明:我最初忽略了恢复一个非聚集索引。这已得到修复,问题也相应更改]

J.D*_*.D. 6

您如何衡量表和索引的大小?

SQL Server 的工作方式是,一旦为数据库分配了磁盘空间,它仍会保留该磁盘空间,并且仅在数据减少/删除时将其标记为空/供内部重用,直到SHRINK发生强制释放所获取的或类似的操作空间回到磁盘。

因此,将固定宽度的数据类型更改为使用较少空间的类型不会自动触发将先前声明的空间释放回磁盘,除非您重建索引、运行 aSHRINK等。

正如马丁在评论中指出的那样,如果您正在使用压缩,那么可能BIGINT只保存INT值的列的已用空间已经被压缩为列的等效空间使用INT,这也可以解释为什么您看不到它通过更改数据类型来更改大小,即使您确实重建了索引或运行了SHRINK操作。

  • `int`/`bigint` 是固定宽度的数据类型,因此除非使用压缩,否则预期大小会减小。当您更改固定宽度列数据类型时,它会在表中创建一个新列并将旧列标记为已删除。在您重建聚集索引或运行 clean table 之前,不会从删除的列中回收空间。 (3认同)