结论:

1、Sqlserver支持针对行存储表和索引的行和页压缩,并且支持针对列存储表和索引的列存储和列存储存档压缩。对于行存储表和索引,使用数据压缩功能可帮助减小数据库的大小。 除了节省空间之外,数据压缩还可以帮助提高 I/O 密集型工作负荷的性能,因为数据存储在更少的页中,查询需要从磁盘读取的页更少。 但是,在与应用程序交换数据时,在数据库服务器上需要额外的 CPU 资源来压缩和解压缩数据。 您可以在以下数据库对象上配置行和页压缩:存储为堆的整个表、存储为聚集索引的整个表、整个非聚集索引、整个索引视图、对于已分区表和已分区索引,可为每个分区配置压缩选项,且对象的各个分区的压缩设置不必相同。
2、压缩功能不可用于系统表。
3、通过压缩可在一页上存储更多的行,但不会更改表或索引的最大行大小。
4、当指定分区列表时,可以将各个分区的压缩类型设置为 ROW、PAGE 或 NONE。 如果未指定分区列表,将使用语句中指定的数据压缩属性来设置所有分区。 创建表或索引时,除非指定了其他压缩设置,否则数据压缩将设置为 NONE。 修改表时,除非指定了其他压缩设置,否则将保留现有压缩设置。
5、当最大行大小加上压缩开销超过最大行大小 8060 个字节时,不能对表启用压缩功能。 例如,不能压缩具有 c1 CHAR(8000) 和 c2 CHAR(53) 列的表,因为存在额外的压缩开销。
create table t12345 (c1 CHAR(8000) , c2 CHAR(50))–正常创建
create table t123456 (c1 CHAR(8000) , c2 CHAR(60))–无法创建,有报错:Creating or altering table ‘t123456’ failed because the minimum row size would be 8067, including 7 bytes of internal overhead. This exceeds the maximum allowable table row size of 8060 bytes.
6、非聚集索引不继承表的压缩属性。 若要压缩索引,必须显式设置索引的压缩属性。 默认情况下,创建索引时,索引的压缩设置会设置为NONE。
7、对堆表创建聚集索引时,聚集索引会继承该堆表的压缩状态,除非指定了另一压缩状态。
8、如果堆表配置为页级压缩,则只有在以下情况下,页才会进行页级压缩:
在启用大容量优化的情况下大容量导入数据。
数据是使用 INSERT INTO … WITH (TABLOCK) 语法插入的,并且表没有非聚集索引。
表是通过执行带 PAGE 压缩选项的 ALTER TABLE … REBUILD 语句重新生成的。
9、通过 DML 操作被分配到堆表中的新页面不会使用 PAGE 压缩,除非重新生成该堆。 重新生成堆的方法有:删除压缩然后重新应用压缩,或者创建聚集索引然后再删除聚集索引。
10、若要更改堆表的压缩设置,要求对表重新生成所有非聚集索引,以便它们具有指向堆表中的新行位置的指针。
11、可以联机或脱机启用或禁用 ROW 或 PAGE 压缩功能。 当执行联机操作时,对堆启用压缩功能是单线程的。
12、启用或禁用行压缩或页压缩的磁盘空间要求与创建或重新生成索引时的磁盘空间要求相同。 对于已分区数据,可以通过每次对一个分区启用或禁用压缩功能来减少所需的空间。
13、压缩索引时,可以使用行压缩和页压缩来压缩叶级页。 非叶级页不接收页压缩。
14、当使用页压缩时,将仅使用行压缩来压缩索引的非叶级别页。
15、使用页压缩压缩表和索引的叶级别的过程由按以下顺序进行的三个操作组成:行压缩、前缀压缩、字典压缩。可以简单理解:PAGE压缩包括ROW压缩,所以PAGE压缩率更高

DATA_COMPRESSION = {NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE}

NONE:不压缩表或指定的分区。 此选项不适用于列存储表。
ROW:使用行压缩来压缩表或指定的分区。 此选项不适用于列存储表。
PAGE:使用页压缩来压缩表或指定的分区。 此选项不适用于列存储表。
COLUMNSTORE:适用于SQL Server(SQL Server 2014 (12.x) 及更高版本)和 Azure SQL 数据库。仅适用于列存储表。
COLUMNSTORE_ARCHIVE:适用于:SQL Server(SQL Server 2014 (12.x) 及更高版本)和 Azure SQL 数据库。仅适用于列存储表。

使用页压缩压缩表和索引的叶级别的过程由按以下顺序进行的三个操作组成:行压缩、前缀压缩、字典压缩

行压缩
减少了与记录相关联的元数据开销。 此元数据为有关列、列长度和偏移量的信息。 在某些情况下,元数据开销可能大于旧的存储格式。
它对于数值类型(例如, integer、 decimal和 float)和基于数值的类型(例如, datetime 和 money)使用可变长度存储格式。
它通过使用不存储空字符的可变长度格式来存储定长字符串。
将对所有数据类型的 NULL 和 0 值进行优化,从而使它们不占用任何字节。
不受压缩影响的字段类型:tinyint、smalldatetime、date、time、varchar、text、nvarchar、ntext、varbinary、xml

前缀压缩
对于要压缩的每一页,前缀压缩采用以下步骤:
对于每一列,将确定一个值,此值可用于减少每一列中的值的存储空间。
将创建表示每一列的前缀值的行,并将其存储在紧随页头之后的压缩信息 (CI) 结构中。
列中重复的前缀值将由指向对应前缀的引用进行替换。 如果行中的值与所选前缀值并不完全匹配,则仍会指示存在部分匹配。

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