稀疏列没有显示任何节省

时间:2013-03-03 13:59:32

标签: sql sql-server null sparse-columns

我运行了一个测试,将一个稀疏列的表与一个没有稀疏列的表进行比较,我看到零空间节省。

我有两个表,都主要在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.
    */

1 个答案:

答案 0 :(得分:3)

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

由于以下原因占用了空间:

  1. AddressID(4个字节)
  2. NULL位图(两个表中的1个字节)
  3. 稀疏列的列表(每个NULL字段2个字节)
  4. 列值列表(不是任何,因为NULL varchars不占空间)
  5. 稀疏列的6字节开销(仅引用为here
  6. 其他一些小额开销
  7. 这可能需要一些解释。两个表都有AddressID,因此占用的空间相同。

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

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

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

    稀疏列只有在有值时占用空间。这里没有人有价值观。

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

    当我在稀疏表中至少有8个稀疏列而不是非稀疏表时,我看到节省了空间。这绝对可以节省NULL位映射,它会向上舍入到最接近的字节。

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

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

    查看文档here