- ClickHouse 中点查询成本高的关键原因,在于主 MergeTree 表引擎家族 使用的是稀疏主索引。这个索引无法定位到每一条具体的行数据,而只能指向每第 N 行;因此系统必须从相邻的第 N 行扫描到目标行,并在过程中读取额外的数据。在键值场景中,适当减小
index_granularity设置中的 N 值可能会有所帮助。 - ClickHouse 将每一列保存在各自独立的一组文件中,因此要拼装出完整的一行数据,就需要遍历这些文件。文件数量会随着列数线性增长,因此在键值场景中,最好避免使用过多的列,而是将所有载荷放进单个
String列中,并用 JSON、Protobuf 或其他合适的序列化格式进行编码。 - 还有一种替代方案:使用 Join 表引擎,而不是普通的
MergeTree表,再通过 joinGet 函数获取数据。这样做可能带来更好的查询性能,但也可能存在一些易用性和可靠性问题。这里有一个使用示例。
我可以将 ClickHouse 用作键值存储吗?
回答关于 ClickHouse 是否可以用作键值存储的常见问题。
简短的答案是 “不能”。键值工作负载恰恰属于不应使用 ClickHouse 的典型场景之一。毕竟它本质上是一个 OLAP 系统,而市面上已经有许多优秀的键值存储系统。
不过,在某些情况下,使用 ClickHouse 处理类键值查询仍然说得通。通常,这类场景出现在预算有限的产品中:主要工作负载本质上是分析型的,并且很适合 ClickHouse,但同时还有某个次要流程需要键值模式,请求吞吐量不高,也没有严格的延迟要求。如果你的预算无限,你可能会为这个次要工作负载再部署一个键值数据库;但在现实中,额外维护一套存储系统 (监控、备份等) 也会带来成本,而这往往是人们希望避免的。
如果你决定不按推荐做,而是让 ClickHouse 执行某些类键值查询,下面是一些建议:
最后修改于 2026年6月10日