南大通用GBase 8a数据库(gbase database)的存储引擎 Express 是纯列存架构,压缩不是可选功能,而是数据写入的标准流程。理解列存压缩的工作原理,能帮助 DBA 和开发人员在建表时做出更好的数据类型选择,在查询优化时理解 I/O 代价的构成,在容量规划时给出更准确的磁盘估算。本文继续介绍GBase 8a数据库(gbase database)在不同数据特征下的最优选择,并给出实际测量压缩效果的方法。
三、影响压缩效果的设计决策
理解了压缩原理,就能在日常建表和查询设计中做出更有意识的选择,而不是把压缩当作黑盒。
数据类型的影响是最直接的。用TINYINT(1 字节)存 0~255 范围的枚举值,远比用VARCHAR(20)存 "active"/"inactive" 压缩效果好——不仅字典编码的字典更小,差值编码也更高效。用DATE存日期而不是VARCHAR(10)存 "2024-06-01",列存引擎可以用专门的日期编码,压缩率和查询时的日期计算性能都更好。用数值类型存 ID,而不是字符串类型,是同样的道理。
写入顺序的影响往往被忽略。列存引擎的 RLE 编码对连续相同值的效果极好,这意味着如果数据按dept_id或order_date排序写入,同一部门或同一日期的数据聚集在一起,RLE 的压缩率会显著高于随机顺序写入的情况。在 gload 的配置文件中,如果源数据已经按某列有序,可以在配置中声明排序列,让引擎利用这个信息优化编码。
列的基数选择在分布键设计时已经讨论过,但它同样影响压缩效率。用customer_id(千万级唯一值)做分布键后,该列在每个 gnode 上的局部分布仍然有较高基数,字典编码的收益有限;但dept_id(百级唯一值)的压缩率就会高得多。这不意味着要为了压缩率去选择低基数列作为分布键,而是说在做容量规划时,高基数分布键列的压缩率要按偏低估算,低基数列按偏高估算,这样整体容量估算会更准确。
四、实测压缩效果
在生产环境中,最准确的压缩率数据来自实际测量,而非公式估算。
通过分列查看,可以发现哪些列的压缩率远低于预期,进而检查这些列的数据类型是否合理(比如用 VARCHAR 存了应该是 INT 的值),或者数据分布是否真的是高基数、高随机性的(这种情况下低压缩率是正常的,无需优化)。
对于即将上线的新系统,建议在上线前用部分生产数据做压缩率摸底测试,把实测的压缩比代入容量规划公式,这比用经验值("按 5:1 算")要准确得多。
五、常见误区
误区一:压缩率越高查询越快。压缩率提升减少了 I/O 量,在 I/O 是瓶颈时确实能加速查询。但如果 CPU 是瓶颈,更高的压缩率意味着更多的解压 CPU 开销,反而可能导致查询变慢。需要结合实际的资源瓶颈位置来判断。
误区二:用字符串存数值不影响压缩。字符串 "12345678" 需要 8 个字节,而 INT 类型的 12345678 只需要 4 个字节,且 INT 类型可以使用差值编码进一步压缩,字符串类型不行。用错数据类型不仅浪费存储,还会让特定的编码优化失效。
误区三:压缩是 DBA 的事,与开发无关。开发人员选择的数据类型和写入顺序直接影响压缩效率。用TINYINT还是VARCHAR存 status,压缩率可能相差 5 倍,查询时的解压开销也相差同等倍数。把压缩效率的考量纳入代码审查和表设计评审,是提升整体系统效率的有效手段。