• SQL SERVER 数据压缩


    从SQL SERVER 2008开始,SQL SERVER 提供了对数据进行压缩的功能,启用数据压缩无须修改应用程序。

    数据压缩可有效减少数据的占用空间,读取和写入相同数据花费的IO也响应减少,从而可以有效缓解IO压力,但由于数据在读取和写入时需要压缩和解压缩,因此会消耗CPU资源,但不代表在相同负载下,启用数据压缩会导致CPU的使用率变高,某些操作会因为数据页数量的减少而降低CPU资源的消耗。

    可以配置数据压缩的对象有:
    1>存储为堆的整个表。
    2>存储为聚集索引的整个表。
    3>整个非聚集索引。
    4>整个索引视图。
    5>对于已分区表和已分区索引,可为每个分区配置压缩选项,且对象的各个分区的压缩设置不必相同。
    (个人理解:数据压缩是在parition级别上使用,未分区表和未分区索引同样可以找到一个对应的partitionID)


    数据压缩方式有两种
    1:行压缩
    2:页压缩


    行压缩实现:
    行压缩更改与数据类型相关联的数据的物理存储格式来实现压缩:
    1>减少了与记录相关联的元数据开销。 此元数据为有关列、列长度和偏移量的信息。 在某些情况下,元数据开销可能大于旧的存储格式。
    2>它对于数值类型(例如,integer、decimal 和 float)和基于数值的类型(例如,datetime 和 money)使用可变长度存储格式。
    3>它通过使用不存储空字符的可变长度格式来存储定长字符串。

    快速理解:
    对应数值类型和基于数值的类型来说,由于需要类型定义范围内的数据,因此需要相对较大的定长空间,如BIGINT占用8个字节,但对于值1来说,只需要一个字节便可以存放,启用行压缩便可以节省7个字节的空间;对于定长数据类型,如果存放的数据未达到指定长度,会补空字符来填满,如类型CHAR(200)用来存放字符串"1"会花费200个字节,但启用行压缩后,会将填充的空字符移除,只需要1个字节便可以存放。而对于类型bit来说,除自身消耗的空间外,还需要额外的4个bit来存放元数据,因此也可以从行压缩中获益。


    行压缩影响的数据类型可参考http://msdn.microsoft.com/zh-cn/library/cc280576.aspx


    页压缩实现:
    页压缩是在行压缩的基础上进行前缀压缩,然后再进行字典压缩


    前缀压缩:前缀压缩针对页中的各列来进行压缩,首先从列中选取出一个前缀值(不要求页中每一行的该列的值都包含此前缀)存放在页头,然后使用该前缀替换页中每一行的该列值,如提起前缀为aabbcc,对应值aabbccdd则替换为6dd,对应值aadd则替换为2dd,对应值ccbbdd则替换成0ccbbdd,对应值aabbcc则替换成[],每行会生成一个前缀来处理。


    字典压缩:字典压缩是在前缀压缩完成后,搜索页面上任意位置的重复值,然后将它们存储在 CI 区域中。 与前缀压缩不同,字典压缩不局限于一列。 字典压缩可以替换页面上任意位置出现的重复值。


    当表和索引使用页压缩后,对于一个新的页面,插入数据行时会对该行启用行压缩,直到该页已满无法存放新增加的行时,才会使用页压缩的算法计算启用页压缩是否能存放新增加的行,如果可以存放,则对该页进行页压缩并将新增加的行放到该页,如果不能存放,则不对该页启用页压缩,申请新页来存放新行。


    在SQL SERVER 2012中,SQL Server 使用 Unicode 标准压缩方案 (Standard Compression Scheme for Unicode, SCSU) 算法实现来压缩在行或页压缩对象中存储的 Unicode 值。 对于这些压缩对象,Unicode 压缩对于 nchar(n) 和 nvarchar(n) 列而言是自动的。 数据库引擎 将 Unicode 数据存储为 2 个字节,无论区域设置如何。 这称为 UCS-2 编码。 对于某些区域设置而言,在 SQL Server 中实现 SCSU 压缩可节省高达 50% 的存储空间。

    数据压缩Demo

    --=============================================================================================================================
    --=========================================================
    --判断表和索引是否启用压缩和压缩类型
    --宋桑提供
    SELECT DISTINCT
    SCHEMA_NAME(o.schema_id)  + '.' + OBJECT_NAME(o.object_id) AS TableName,
    i.name AS IndexName,
    p.data_compression_desc AS CompressionType,
    i.type_desc AS StorageType
    FROM sys.partitions  p  with(nolock)
    INNER JOIN sys.objects o with(nolock)
    ON p.object_id = o.object_id 
    JOIN sys.indexes i 
    ON p.object_id = i.object_id
    AND i.index_id = p.index_id
    WHERE p.data_compression > 0 
    AND SCHEMA_NAME(o.schema_id) <> 'SYS' 
    
    
    --=========================================================
    --使用采样来预估数据对象启用压缩前后的空间使用
    --参考链接:http://msdn.microsoft.com/zh-cn/library/cc280574.aspx
    --PS:该算法只能起参考作用,数据压缩得到的空间可能比预估的要大很多
    EXEC sp_estimate_data_compression_savings 'dbo', 'TB', NULL, NULL, 'ROW' ;
    
    --=========================================================
    --对表使用数据压缩
    ALTER TABLE  <table_name>
    REBUILD PARTITION = ALL 
    WITH (DATA_COMPRESSION = PAGE|ROW)
    
    --=========================================================
    --对表中特定分区指定压缩
    ALTER TABLE <table_name> 
    REBUILD PARTITION = 1 WITH (DATA_COMPRESSION =  PAGE|ROW)
    
    --=========================================================
    --对表中多个特定分区指定压缩
    ALTER TABLE <table_name> 
    REBUILD PARTITION = ALL 
    WITH (DATA_COMPRESSION = PAGE ON PARTITIONS(<range>),
    ... )
    --=========================================================
    --在新建索引时指定压缩
    CREATE CLUSTERED INDEX [CLX_ID] ON [dbo].[TB2] 
    (
        [ID] ASC
    )WITH (DATA_COMPRESSION = { NONE | ROW | PAGE}) ON [PRIMARY]
    GO
    
    --=========================================================
    --使用重建索引来进行压缩
    ALTER INDEX [CLX_ID] ON [dbo].[TB2] REBUILD PARTITION = ALL 
    WITH ( DATA_COMPRESSION = { NONE | ROW | PAGE })
    
    
    --=============================================================================================================================


    压缩试验:
    压缩表定义为:

    CREATE TABLE [dbo].[TB1](
     [id] [bigint] IDENTITY(1,1) PRIMARY KEY,
     [star_uid] [bigint] NOT NULL,
     [source_uid] [bigint] NOT NULL,
     [site_type] [tinyint] NOT NULL,
     [site_server_type] [tinyint] NOT NULL,
     [site_id] [bigint] NOT NULL,
     [count] [int] NOT NULL,
     [create_date] [bigint] NOT NULL,
     ) ON [PRIMARY]


    压缩前占用空间:7309288KB
    压缩后占用空间:2594624KB
    压缩使用时间:3分58秒
    压缩环境:8Core 32G 4块SAS(15000转4盘片)做RAID 10

    --未完待续

    参考链接:http://msdn.microsoft.com/zh-cn/library/cc280449.aspx

    惯例上图引狼

  • 相关阅读:
    装饰器的用法——用装饰器来记录函数被调用的次数
    类和对象(上) C++
    数据结构—树(二叉树)
    数据结构—顺序表
    c++入门

    Cypress博客
    自动化测试框架总结2
    前端测试框架Jest总结
    关于redux和react书籍源码系列代码
  • 原文地址:https://www.cnblogs.com/TeyGao/p/3545004.html
Copyright © 2020-2023  润新知