我运行了一个测试,将一个稀疏列的表与一个没有稀疏列的表进行比较,我看到零空间节省。
我有两个表,都主要在varchar列中存储地址信息。 两个表都允许空值,其中一个表具有列稀疏属性集。
我在每个中插入1000行默认值(默认值为null)。稀疏列以不同方式存储空值,因此我相信我应该看到节省空间。但在运行sp_spaceUsed时我没有看到任何保存。关于我做错了什么或我的理解不正确的任何想法?
Create Table SparseColTest_NonSparse
(
AddressID int identity(1,1) not null,
AddressLine1 varchar(500) null,
AddressLine2 varchar(500) null,
AddressLine3 varchar(500) null,
PostalCode varchar(20) null,
Country varchar(50)
)
Create Table SparseColTest_Sparse
(
AddressID int identity(1,1) not null,
AddressLine1 varchar(500) sparse null,
AddressLine2 varchar(500) sparse null,
AddressLine3 varchar(500) sparse null,
PostalCode varchar(20) sparse null,
Country varchar(50)
)
declare @i int
set @i = 0
while(@i <= 100000)
BEGIN
insert into SparseColTest_NonSparse Default values
insert into SparseColTest_Sparse default values
set @i = @i + 1
END
exec sp_spaceUsed 'SparseColTest_NonSparse'
exec sp_spaceUsed 'SparseColTest_Sparse'
/*
name rows reserved data index_size unused
----------------------------- -------------------- ------------------ ------------- ----- ------------------ ------------------
SparseColTest_NonSparse 210003 2888 KB 2840 KB 8 KB 40 KB
name rows reserved data index_size unused
----------------------------- -------------------- ------------------ ------------- ----- ------------------ ------------------
SparseColTest_Sparse 210003 2888 KB 2840 KB 8 KB 40 KB
****NOTE - even with 210k rows sparse and non sparse tables are identical in size.
*/
答案 0 :(得分:3)
问题是页面上的存储。这是发生的事情的近似值。
由于以下原因占用了空间:
这可能需要一些解释。两个表都有AddressID
,因此占用的空间相同。
所有非稀疏列都在NULL位图中。你可能认为只有 NULL-able 那些,但没有。 SQL Server具有所有这些的位图。一次存储一个字节。因此,非稀疏表中的六列与稀疏表中的两个非稀疏列(标识和国家/地区)占用相同的空间。
变量是可变长度数据。当为NULL时,它们仍然为每列保留2个字节。所以这是第一条记录中的10个字节。第二个是2个字节。
稀疏记录的开销为6个字节。
稀疏列只有在有值时占用空间。这里没有人有价值观。
最终结果是在开销和可能的字节对齐限制之间,在两个记录中加起来相同的长度。非稀疏表中相应列的值占用了长度的一些空间,这似乎与列使用的空间相匹配。我还怀疑页面上的数据行在2字节或4字节边界上对齐。两个表中的NULL位图大小相同。
当我在稀疏表中至少有8个稀疏列而不是非稀疏表时,我看到节省了空间。这绝对可以节省NULL位映射,它会向上舍入到最接近的字节。
稀疏列的实际节省是固定长度的数据类型。存储每个值的开销更大,但这就是稀疏性的来源。值不多。您将失去该值所占空间的位掩码和的开销。
对于您的示例,稀疏列无用。使用真实数据,它们实际上可能会增加存储空间。
查看文档here。