当前位置:首页 > 问答 > 正文

SQL Server里头那个数据压缩功能到底是怎么回事,能帮忙节省多少空间啊

SQL Server里的数据压缩功能,就是微软在数据库引擎内部内置的一种“压缩算法”,它不像我们平时用WinRAR或7-Zip那样把整个数据库文件打包成一个压缩包,而是在数据库内部,对表或索引的数据页进行压缩,从而让一个数据页能装下更多的数据行,这样一来,存储同样多的数据,所需要的物理空间就自然变少了,这个功能不是免费的,它需要企业版或开发版等特定版本的SQL Server才能使用。

SQL Server里头那个数据压缩功能到底是怎么回事,能帮忙节省多少空间啊

它是怎么做到压缩的呢?主要分为两种类型:行压缩和页压缩,根据微软官方文档(MSDN库中关于数据压缩的主题)的解释,我们可以这样理解:

第一种,行压缩,这个听起来好像是在压缩一行数据,其实它的核心思路是“精打细算”,改变数据在行内的存储格式,用更高效的方式来存放数据,举个例子,我们定义一个表,有一个字段是int类型,理论上int可以存储从负二十多亿到正二十多亿的数值,但如果我们实际只存储比如年龄这样的数据,最大也就200吧,那么正常情况下,SQL Server还是会为这个字段预留4个字节的空间,而行压缩会识别到这一点,它发现你存的数值其实很小,就用1个字节来存,这样就省下了3个字节,对于固定长度的字段(比如char(10)),如果你只存了“abc”3个字符,它也不会傻乎乎地仍然占用10个字符的空间,而是只存实际内容,这种压缩方式CPU开销比较小,属于一种“轻量级”压缩。

SQL Server里头那个数据压缩功能到底是怎么回事,能帮忙节省多少空间啊

第二种,页压缩,这就更进了一步,可以理解为“大力出奇迹”,页压缩是在行压缩的基础上,再增加两种压缩技术:前缀压缩和字典压缩,根据微软的说明,前缀压缩是这样的:假设一个数据页里有多行数据,某一列的值都很相似,比如第一行是“ABCDE”,第二行是“ABCDF”,第三行是“ABCDG”,那么压缩时,它会找出这些值共同的前缀“ABCD”,然后只存一次这个前缀,后面的行只存储不同的后缀部分,E”、“F”、“G”,而字典压缩则是在整个页面的范围内,寻找任何重复出现的字节模式,无论它在哪一列,然后创建一个“字典”来替换这些重复值,页压缩的压缩率更高,对CPU的消耗也会比行压缩大。

接下来是大家最关心的问题:到底能节省多少空间?这个没有一个固定的答案,因为它完全取决于你数据的特性,微软在其技术文档和白皮书中提供过一些典型的示例和平均值,但实际情况千差万别,以下几种情况压缩效果会非常显著:

  1. 重复数据多的表:比如一些日志表、配置表、历史数据表,里面有很多字段的值是重复的,比如状态码、类型标识等,这种数据特别适合页压缩,字典压缩能发挥巨大作用。
  2. 数字类型字段多,且数值普遍较小:就像前面年龄的例子,如果表里有很多int, bigint, decimal等数字类型的字段,但实际存储的值远小于数据类型允许的最大值,那么行压缩就能省下可观的空间。
  3. 固定长度字符串字段(char, nchar),但实际数据长度变化大:如果你定义了一个char(100)的字段,但平均只存了20个字符,那么压缩后,那些空着的位置就都能省下来。
  4. 允许大量NULL值的表:在未压缩的情况下,NULL值通常也会占用一定的存储空间,而压缩后,这些NULL值的存储开销会被极大地优化。

根据微软和一些技术社区的实践经验,空间节省幅度可以从百分之二三十到百分之七八十不等,对于一些极其理想的情况(比如全是重复代码和数字的状态表),压缩率甚至可能超过90%,但对于那些已经被加密的数据,或者本来就是压缩格式的数据(如图片、视频二进制数据),压缩效果就微乎其微了,有时甚至可能因为压缩算法的元数据导致体积略微增大。

必须谈谈代价,压缩不是免费的午餐,它本质上是“用CPU换磁盘空间”,当你要插入、更新或读取被压缩的数据时,数据库引擎需要额外进行压缩和解压缩的操作,这会增加CPU的负担,如果你的系统已经是CPU瓶颈,那么启用压缩可能会让性能雪上加霜,但如果你的系统瓶颈在于磁盘I/O(读写速度慢),那么压缩反而可能提升性能,因为数据量变小了,从磁盘读取所需的数据页就少了,同样,写入磁盘的数据量也少了,这能减轻I/O压力。

在决定是否使用压缩、对哪些表使用压缩、以及使用行压缩还是页压缩时,需要一个权衡,通常的做法是,先在测试环境使用SQL Server自带的存储过程(比如sp_estimate_data_compression_savings)来评估一下压缩大概能节省多少空间,然后结合生产环境的CPU和磁盘使用情况,做出明智的选择,对于查询远多于更新的历史数据表、数据仓库中的大表,压缩通常是一个性价比非常高的选择。

SQL Server里头那个数据压缩功能到底是怎么回事,能帮忙节省多少空间啊