跳转到主要内容
ClickHouse 查询高性能的秘诀之一就是压缩。 磁盘上的数据越少,I/O 就越少,查询和插入也就越快。对于 CPU 而言,在大多数情况下,压缩算法带来的开销都会被 I/O 减少所带来的收益抵消。因此,要确保 ClickHouse 查询足够快,首先应关注提升数据压缩效果。
想了解 ClickHouse 为何能如此高效地压缩数据,我们建议阅读这篇文章。简而言之,我们的列式数据库按列顺序写入值。对这些值进行排序后,相同的值会彼此相邻,而压缩算法能够利用数据中连续出现的模式。除此之外,ClickHouse 还提供 编解码器 和更细粒度的数据类型,让你能够进一步轻松优化压缩效果。
ClickHouse 中的压缩会受到 3 个主要因素的影响:
  • 排序键
  • 数据类型
  • 使用了哪些 编解码器
所有这些都通过 schema 进行配置。

选择合适的数据类型来优化压缩

我们以 Stack Overflow 数据集为例。下面比较 posts 表在以下 schema 下的压缩统计信息:
  • posts - 未做类型优化,且没有排序键的 schema。
  • posts_v3 - 经过类型优化的 schema,为每一列都选择了合适的类型和位宽,并使用排序键 (PostTypeId, toDate(CreationDate), CommentCount)
使用以下查询,我们可以度量每一列当前的压缩后大小和未压缩大小。下面先来看没有排序键的初始 schema posts 的大小。
如果你看到 compressed_sizeuncompressed_size 的值为 0,这可能是因为 parts 的类型是 compact 而不是 wide (请参阅 system.partspart_type 的说明) 。 part 格式由设置 min_bytes_for_wide_partmin_rows_for_wide_part 控制。这意味着,如果插入的 数据生成的 part 没有超过上述设置的阈值,那么该 part 就会是 compact, 而不是 wide,因此你将看不到 compressed_sizeuncompressed_size 的值。下面演示这一点:
查询
响应
这里同时展示了压缩大小和未压缩大小,这两者都很重要。压缩大小对应于我们需要从磁盘读取的数据量——为了提升查询性能 (以及降低存储成本) ,我们希望尽可能减小它。数据在读取前还需要先解压。而未压缩大小在这里则取决于所使用的数据类型。尽量减小这一大小,可以降低查询的内存开销和需要处理的数据量,从而提高缓存利用率,并最终缩短查询时间。
上述查询依赖系统数据库中的 columns 表。该数据库由 ClickHouse 管理,堪称一个信息宝库,其中包含从查询性能指标到后台 cluster 日志等大量实用信息。对于想进一步了解的读者,我们推荐阅读 “System Tables and a Window into the Internals of ClickHouse” 及其配套文章[1][2]
如果要汇总表的总大小,我们可以将上面的查询简化为:
posts_v3 (采用了优化后数据类型和排序键的表) 重复执行此查询后,可以看到未压缩大小和压缩后大小都明显减小。
完整的列明细表显示,通过在压缩前先对数据排序并使用合适的类型,BodyTitleTagsCreationDate 这些列的存储空间可显著减少。

选择合适的列压缩编解码器

借助列压缩编解码器,我们可以更改用于对每一列进行编码和压缩的算法 (及其设置) 。 编码和压缩的实现方式略有不同,但目标一致:减小数据体积。编码会利用数据类型的特性,基于某种函数对数据进行映射,从而转换其值。相较之下,压缩则是在字节层面使用通用算法来压缩数据。 通常会先进行编码,再进行压缩。由于不同的编码和压缩算法对不同的值分布效果各异,因此我们必须了解自己的数据。 ClickHouse 支持大量编解码器和压缩算法。以下是一些按重要性排序的建议: 更多选项请参见这里 下面我们为 IdViewCountAnswerCount 指定 Delta 编解码器,假设它们与排序键线性相关,因此应能从 Delta 编码中受益。
这些列的压缩改进如下:

ClickHouse Cloud 中的压缩

在 ClickHouse Cloud 中,我们默认使用 ZSTD 压缩算法 (默认值为 1) 。这种算法的压缩速度会随压缩级别而变化 (级别越高,速度越慢) ,但它的优势在于解压速度始终很快 (波动约 20%) ,并且还支持并行处理。我们过往的测试还表明,这种算法通常已经足够高效,甚至可能优于结合 codec 使用的 LZ4。它对大多数数据类型和数据分布都很有效,因此是一个合理的通用默认选择,这也是为什么即使不做优化,我们的初始压缩效果也已经非常出色。
最后修改于 2026年6月10日