1

我已经进行了一项测试,将具有一些稀疏列的表与没有稀疏列的表进行比较,并且我看到节省空间为零。

我有两个表,都主要在 varchar 列中存储地址信息。两个表都允许空值,一个具有列稀疏属性集。

我在每个中插入 1000 行默认值(默认值为空)。稀疏列以不同的方式存储空值,所以我相信我应该看到节省空间。但是在运行 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.
    */
4

1 回答 1

3

问题是页面上的存储。这是所发生情况的近似值。

占用空间的原因如下:

  1. 地址 ID(4 个字节)
  2. NULL 位图(两个表中的 1 个字节)
  3. 稀疏列列表(每个 NULL 字段 2 个字节)
  4. 列值列表(不是任何值,因为 NULL varchars 不占用空间)
  5. 稀疏列的 6 字节开销(此处仅参考)
  6. 其他一些小开销

这可能需要一些解释。两个表都有AddressID, 占用相同的空间。

所有非稀疏列都在 NULL 位图中。您可能认为只有NULL-able会在那里,但没有。SQL Server 具有所有这些的位图。一次存储一个字节。因此,非稀疏表中的六个列与稀疏表中的两个非稀疏列(身份和国家/地区)占用相同的空间。

Varchars 是可变长度数据。当为 NULL 时,它们仍然为每列保留 2 个字节。所以这是第一条记录中的 10 个字节。第二个是 2 个字节。

稀疏记录有 6 个字节的开销。

稀疏列仅在有值时才占用空间。这里没有值。

最终结果是,在开销和可能的字节对齐限制之间,两条记录的长度加起来相同。非稀疏表中相应列的值占用了一些长度空间,这似乎与列使用的空间相匹配。我还怀疑页面上的数据行在 2 或 4 字节边界上对齐。两个表中的 NULL 位图大小相同。

当稀疏表中的稀疏列比非稀疏表至少多 8 列时,我看到了空间节省。这无疑为您节省了 NULL 位图,它被四舍五入到最接近的字节。

稀疏列的真正节省在于固定长度的数据类型。存储每个值的开销更大,但这就是稀疏性的来源。值并不多。您失去了位掩码值将占用的空间的开销。

对于您的示例,稀疏列没有用。对于真实数据,它们实际上可能会增加存储空间。

在此处查看文档。

于 2013-03-03T17:31:25.947 回答