我们有一个将重新设计的 SQL 数据库。我们要将一些列类型从 INT 更改为 TINYINT。通过这种转换,我们可以减少数据库的磁盘长度,或者这种转换不会显着减少磁盘空间?数据库版本为 SQL Server 2008 R2 32bits。
问问题
373 次
2 回答
3
我们要将一些列类型从 INT 更改为 TINYINT。
注 1(我的观点):真正的问题不在于磁盘上的存储,而在于缓冲池。
注意 2:为列选择正确的数据类型(例如MyColumn
)会影响以下数据库结构的大小:
- 首先是堆/聚集索引大小,然后是
- {Non-clustered index|xml index|spatial index} size if
MyColumn
if part if clustered index key 因为聚集索引键在每个非聚集索引行中重复,在每个主xml 索引中重复(我不是 100% 确定:并且在每个二级 xml 'FOR PROPERTY' 索引中)并且在每个空间索引中重复。 - 非聚集索引大小如果
MyColumn
是索引的一部分(作为键或作为覆盖列(SQL2005+,请参阅 参考资料CREATE ... INDEX ... ON ... INCLUDE()
)。 - 如果
MyColumn
有 {PRIMARY KEY 约束|UNIQUE 约束+NOT NULL|UNIQUE 索引+NOT NULL} 并且如果有引用的外键,MyColumn
那么这些 FK 必须具有相同的数据类型、最大长度、精度、比例和排序规则,如MyColumn
(PK/UQ )。当然,这些 FK 也可以被索引(聚集/非聚集索引)。 - 如果
MyColumn
包含在索引视图中。索引视图可以具有唯一的聚集和非聚集索引,因此MyColumn
可以再次复制。 - 如果
MyColumn
有{a PRIMARY KEY 约束|a UNIQUE 约束+NOT NULL|a UNIQUE 索引+NOT NULL},则它们在引用此列的每个全文索引CREATE FULLTEXT INDEX ... KEY unique_index_name
中都重复(请参阅 参考资料)。 - 未涵盖的主题:列存储索引 (SQL2012+)。
所以,是的,更改某些列的数据类型可能会产生很大的影响。您可以使用此脚本:
SELECT i.object_id, i.index_id, i.name, i.type_desc, ips.page_count, ips.*
FROM sys.indexes i
INNER JOIN sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') AS ips ON i.object_id = ips.object_id AND i.index_id = ips.index_id
WHERE i.name IN (
N'PK_PurchaseOrderHeader_PurchaseOrderID', ...
)
ORDER BY i.object_id, i.index_id;
找出在数据类型更改之前和之后每个 {heap structure|index} 有多少页。
于 2013-07-24T11:53:45.167 回答
1
对于从 INT 更改为 TINYINT 的每一列,它会将行大小减少 3 个字节。不过,您之后可能需要手动回收空间。重建聚集索引将执行此操作。
于 2013-07-24T10:44:59.560 回答