ClickHouseInc

2025 年 ClickHouse 有多猛?Alexey 亲选功能盘点:UPDATE、向量索引、Data Lake 全面起飞

图片

本文字数:10112;估计阅读时间:26 分钟

作者:Alexey Milovidov

Image

随着这一年的结束,我们也迎来了第 12 个版本的发布,因此我想借此机会回顾一下今年我最喜欢的一些功能。

2025 年发布的 ClickHouse 版本共引入了 277 个新功能 🦃、319 项性能优化 ⌚,以及 1,051 个 Bug 修复 🍄

你可以通过下面的链接查看每个版本对应的发布博客文章:

25.1、25.2、25.3 LTS、25.4、25.5、25.6、25.7、25.8 LTS、25.9、25.10、25.11

25.12 版本的发布博客文章已于 2026 年初发布!

Image

新贡献者

在此特别欢迎所有于 2025 年加入的新贡献者!ClickHouse 社区的快速成长令人由衷敬佩,我们也始终感谢每一位贡献者,正是你们的付出让 ClickHouse 变得如此受欢迎。

以下是今年新增贡献者的名单:

0xgouda, AbdAlRahman Gad, Agusti Bau, Ahmed Gouda, Albert Chae, Aleksandr Mikhnenko, Aleksei Bashkeev, Aleksei Shadrunov, Alex Bakharew, Alex Shchetkov, Alexander Grueneberg, Alexei Fedotov, Alon Tal, Aly Kafoury, Amol Saini, Andrey Nehaychik, Andrey Volkov, Andrian Iliev, Animesh, Animesh Bilthare, Antony Southworth, Arnaud Briche, Artem Yurov, Austin Bonander, Bulat Sharipov, Casey Leask, ChaiAndCode, Cheryl Tuquib, Cheuk Fung Keith (Chuck) Chow, Chris Crane, Christian Endres, Colerar, Damian Maslanka, Dan Checkoway, Danylo Osipchuk, Dasha Wessely, David E. Wheeler, David K, DeanNeaht, Delyan Kratunov, Denis, Denis K, Denny [DBA at Innervate], Didier Franc, Diskein, Dmitry Novikov, Dmitry Prokofyev, Dmitry Uvarov, Dominic Tran, Drew Davis, Dylan, Elmi Ahmadov, Engel Danila, Evgenii Leko, Felix Mueller, Fellipe Fernandes, Fgrtue, Filin Maxim, Filipp Abapolov, Frank Rosner, GEFFARD Quentin, Gamezardashvili George, Garrett Thomas, George Larionov, Giampaolo Capelli, Grant Holly, Greg Maher, Grigory Korolev, Guang, Guang Zhao, H0uston, Hans Krutzer, Harish Subramanian, Himanshu Pandey, Huanlin Xiao, HumanUser, Ilya Kataev, Ilya fanyShu, Isak Ellmer, Ivan Nesterov, Jan Rada, Jason Wong, Jesse Grodman, Jia Xu, Jimmy Aguilar Mena, Joel Höner, John Doe, John Zila, Jony Mohajan, Josh, Joshie, Juan A. Pedreira, Julian Meyers, Julian Virguez, Kai Zhu, Kaviraj, Kaviraj Kanagaraj, Ken LaPorte, Kenny Sun, Konstantin Dorichev, KovalevDima, Krishna Mannem, Kunal Gupta, Kyamran, Leo Qu, Lin Zhong, Lonny Kapelushnik, Lucas Pelecq, Lucas Ricoy, Luke Gannon, László Várady, Manish Gill, Manuel, Manuel Raimann, Mark Roberts, Marta Paes, Maruth Goyal, Max Justus Spransy, Melvyn Peignon, Michael Anastasakis, Michael Ryan Dempsey, Michal Simon, Mikhail Kuzmin, Mikhail Tiukavkin, Mishmish Dev, Mithun P, Mohammad Lareb Zafar, Mojtaba Ghahari, Muzammil Abdul Rehman, NamHoaiNguyen, Narasimha Pakeer, Neerav, Nick, Nihal Z., Nihal Z. Miaji, Nikita Vaniasin, Nikolai Ryzhov, Nikolay Govorov, NilSper, Nils Sperling, Oleg Doronin, Olli Draese, Onkar Deshpande, ParvezAhamad Kazi, Patrick Galbraith, Paul Lamb, Pavel Shutsin, Pete Hampton, Philip Dubé, Q3Master, Rafael Roquetto, Rajakavitha Kodhandapani, Raphaël Thériault, Raufs Dunamalijevs, Renat Bilalov, RinChanNOWWW, Rishabh Bhardwaj, Roman Lomonosov, Ronald Wind, Roy Kim, RuS2m, Rui Zhang, Sachin Singh, Sadra Barikbin, Sahith Vibudhi, Saif Ullah, Saksham10-11, Sam Radovich, Samay Sharma, Sameer Tamsekar, San Tran, Sante Allegrini, Saurav Tiwary, Sav, Sergey, Sergey Lokhmatikov, Sergio de Cristofaro, Shahbaz Aamir, Shakhaev Kyamran, Shankar Iyer, Shaohua Wang, Shiv, Shivji Kumar Jha, Shreyas Ganesh, Shruti Jain, Somrat Dutta, Spencer Torres, Stephen Chi, Sumit, Surya Kant Ranjan, Tanin Na Nakorn, Tanner Bruce, Taras Polishchuk, Tariq Almawash, Todd Dawson, Todd Yocum, Tom Quist, Vallish, Vico.Wu, Ville Ojamo, Vlad Buyval, Vladimir Baikov, Vladimir Zhirov, Vladislav Gnezdilov, Vrishab V Srivatsa, Wudidapaopao, Xander Garbett, Xiaozhe Yu, Yanghong Zhong, YjyJeff, Yunchi Pang, Yutong Xiao, Zacharias Knudsen, Zakhar Kravchuk, Zicong Qu, Zypperia, abashkeev, ackingliu, albertchae, alburthoffman, alistairjevans, andrei tinikov, arf42, c-end, caicre, chhetripradeep, cjw, codeworse, copilot-swe-agent[bot], craigfinnelly, cuiyanxiang, dakang, ddavid, demko, dollaransh17, dorki, e-mhui, f.abapolov, f2quantum, felipeagfranceschini, fhw12345, flozdra, flyaways, franz101, garrettthomas, gvoelfin, haowenfeng, haoyangqian, harishisnow, heymind, inv2004, jemmix, jitendra1411, jonymohajanGmail, jskong1124, kirillgarbar, krzaq, lan, lomik, luxczhang, mekpro, mkalfon, mlorek, morsapaes, neeravsalaria, nihalzp, ollidraese, otlxm, pheepa, polako, pranav mehta, r-a-sattarov, rajatmohan22, randomizedcoder [email protected], restrry, rickykwokmeraki, rienath, romainsalles, roykim98, samay-sharma, saurabhojha, sdairs, shanfengp, shruti-jain11, sinfillo, somrat.dutta, somratdutta, ssive7b, sunningli, talmawash, tdufour, tiwarysaurav, tombo, travis, wake-up-neo, wh201906, wujianchao5, xander, xiaohuanlin, xin.yan, yahoNanJing, yangjiang, yanglongwei, yangzhong, yawnt, ylw510, zicongqu, zlareb1, zouyunhe, |2ustam, Андрей Курганский, Артем Юров, 思维

我最近在 ClickHouse 旧金山 meetup 上分享了我最喜欢的一些功能,你也可以查看这次分享所使用的演示幻灯片(https://presentations.clickhouse.com/2025-meetupsf-3/top_features/#23)。

下面正式进入我今年最喜欢的功能介绍。

Image

轻量级更新 

在 ClickHouse 25.7 中,我们引入了对大规模标准 SQL UPDATE 语句的支持,这一特性也被称为轻量级更新 (lightweight updates) 。

该特性基于一种轻量级的 patch-part 机制实现。与传统的 mutation 不同,后者需要重写整列数据,而轻量级更新只会写入非常小的 “patch part”,能够几乎即时生效,并且对查询性能的影响极小。

现在,如果我们需要更新某一行数据,只需编写如下所示的查询即可:

UPDATE ordersSET discount = 0.2WHERE quantity >= 40;

在内部实现上,ClickHouse 会插入一个紧凑的 patch part,在后续的合并过程中对数据 part 进行修补,仅应用发生变化的那部分数据。

Image

由于合并操作本身就已经在后台持续运行,现在只是在合并过程中额外应用 patch part,从而在 part 合并时高效地更新底层数据。

更新几乎会立即对查询可见 —— 尚未合并的 patch part 会针对每个数据流中对应的数据范围独立匹配并应用,以一种精准且有针对性的方式执行,既保证了更新的正确性,又不会影响系统的并行执行能力:

Image

同样地,你也可以使用标准 SQL 语法来执行数据删除操作:

DELETE FROM ordersWHERE order_id = 1001AND item_id = 'mouse';

ClickHouse 会生成一个 patch part,将被删除行的 _row_exists 设置为 0,随后这些行会在下一次后台合并时被真正移除。

关于该特性的更多细节,可以参考 ClickHouse 25.7 的发布博客文章。如果你希望进一步深入理解,还可以阅读 Tom Schreiber 撰写的三篇关于 ClickHouse 中高速 UPDATE 的博客系列:

  • 第一部分:专用引擎

    介绍 ClickHouse 如何通过基于插入的引擎(例如 ReplacingMergeTree、CollapsingMergeTree 和 CoalescingMergeTree)来规避缓慢的行级更新。

  • 第二部分:声明式 SQL 风格的 UPDATE

    讲解我们是如何利用 patch part 机制,以极低的额外开销将标准 UPDATE 语法引入 ClickHouse 的。

  • 第三部分:基准测试

    展示这一方案的实际性能表现。我们对所有方案(包括声明式 UPDATE)进行了基准测试,最高可实现 1,000× 的速度提升。

  • 附加内容:ClickHouse vs PostgreSQL(https://clickhouse.com/blog/update-performance-clickhouse-vs-postgresql)

    在相同硬件条件和数据一致性的前提下,我们将 ClickHouse 全新的 SQL UPDATE 与 PostgreSQL 进行了正面对比,在批量修改场景下速度最高可快达 4,000×。

Image

Data Lake 支持

多年来我们一直看到,诸如 Iceberg 和 Delta Lake 这样的开放表格式正在数据生态系统中迅速普及,并获得了越来越多的关注。

ClickHouse 在 23.2 版本中引入了对 Iceberg 的直接查询支持,但到 2024 年底,我们已经清楚地认识到,要想真正与这些表格式深度集成,必须具备完整的 catalog 层支持。

在 2025 年这一年里,我们对数据湖能力进行了快速扩展。年初率先支持了 REST 和 Polaris catalogs ,而到年底,ClickHouse 已经为主流 catalog 系统提供了对应的数据库引擎:

  • REST 和 Polaris catalogs(自 24.12 起)

  • Unity catalog(自 25.3 起)

  • Glue catalog(自 25.3 起)

  • Hive Metastore catalog(自 25.5 起)

  • Microsoft OneLake(自 25.11 起)

在 24.11 到 25.8 版本之间,ClickHouse 在数据湖功能上的变化是质的飞跃。下表展示了 ClickHouse 如何从几乎不具备数据湖能力,逐步发展到覆盖全面的数据湖特性:

Feature

ClickHouse 24.11

ClickHouse 25.8

Catalog(Unity、Rest catalog、Polaris、...)

❌

✅

分区裁剪

❌

✅

基于统计信息的裁剪

❌

✅

缓存改进

❌

✅

模式演进(Schema Evolution)

❌

✅

时间回溯(Time Travel)

❌

✅

内省(Introspection)

❌

✅

基于位置的删除 

❌

✅

基于等值条件的删除

❌
✅

写入支持

❌

✅

Image

Text index

ClickHouse 在全文搜索方向上的探索可谓一波三折。相关开发最早可以追溯到 2022 年,Harry Lee 和 Larry Luo 于 2023 年完成了最初的原型实现。此后,这一特性的推进并非一气呵成,而是在接下来的几年中经历了多次暂停与重启。

最终,为了达到生产环境可用的标准,该特性被彻底重写。文本索引在 25.9 版本中以实验性功能的形式引入,并计划在 ClickHouse 25.12 中升级为 beta 状态。

文本索引可以像下面这样定义在表的某一列上:

CREATE TABLE hackernews(    `id` Int64,    `deleted` Int64,    `type` String,    `by` String,    `time` DateTime64(9),    `text` String,    `dead` Int64,    `parent` Int64,    `poll` Int64,    `kids` Array(Int64),    `url` String,    `score` Int64,    `title` String,    `parts` Array(Int64),    `descendants` Int64,    INDEX inv_idx(text)    TYPE text(tokenizer = 'splitByNonAlpha')    GRANULARITY 128)ORDER BY time;

定义完成后,它就可以用于加速使用以下文本函数的查询:

SELECT by, count()FROM hackernewsWHERE hasToken(text, 'OpenAI')GROUP BY ALLORDER BY count() DESCLIMIT 10;
SELECT by, count()FROM hackernewsWHERE hasAllTokens(text, ['OpenAI', 'Google'])GROUP BY ALLORDER BY count() DESCLIMIT 10;
SELECT by, count()FROM hackernewsWHERE hasAnyTokens(text, ['OpenAI', 'Google'])GROUP BY ALLORDER BY count() DESCLIMIT 10;

我们在一个规模为 50 TB 的日志数据集上对文本索引进行了测试,其在大规模场景下表现稳定且高效。下面的动画展示了在不使用任何索引、使用 bloom filter 以及使用文本索引时执行查询的对比情况:

Image

下方的图表则展示了这三种方案之间的相对性能差异:

Image

Image

Vector index

ClickHouse 中的向量搜索功能同样经历了多年的持续演进。最早的实验性版本可以追溯到 22.9,这一成果来自 Arthur Filatenkov、Vladimir Makarov、Danila Mishin、Nikita Vasilenko、Alexander Piachonkin、Nikita Evsiukov 以及 Hakob Sagatelyan 的共同努力。

一年之后,在 23.8 版本中,Davit Vardanyan 将 USearch 库集成进 ClickHouse,为平台引入了更加成熟和稳定的向量相似度搜索能力。

真正的突破出现在今年。25.1 版本中,Shankar Iyer、Robert Schulze 和 Michael Kolupaev 为向量索引带来了显著的性能提升。随后在 25.5 版本,随着预过滤(prefiltering)、后过滤(postfiltering)以及重评分(rescoring)等关键生产级能力的加入,这一功能正式进入 beta 状态,这些特性同样由 Shankar Iyer 和 Robert Schulze 实现。

最终,在 25.8 版本中,向量搜索达到了正式可用(GA)状态,并新增了仅索引读取(index-only reading)、fetch multiplier 支持以及二进制量化(binary quantization),在性能与资源效率方面进一步优化。

在本文撰写时,ClickHouse 仅支持一种近似搜索方法 —— HNSW。这是一种业界广泛采用、技术先进的近似向量搜索算法,基于分层邻近图实现。我们可以像下面这样在某一列上定义向量索引:

CREATE TABLE wikiEmbeddings (  id Int32,  title String,  text String,  url String,  wiki_id Int32,  views Float32,  paragraph_id Int32,  langs Int32,  emb Array(Float32),  INDEX emb_hnsw emb TYPE vector_similarity('hnsw', 'L2Distance', 768))ORDER BY id;

随后即可编写使用该索引的查询:

WITH (SELECT emb FROM wikiEmbeddings WHERE id = 120356) AS lookupSELECT id, title, text, url, L2Distance(emb, lookup) AS distFROM wikiEmbeddingsORDER BY distLIMIT 3FORMAT Vertical;

该方向上的另一个有趣进展是 Raufs Dunamalijevs 引入的 QBit。这是一种专为向量嵌入设计的数据类型,允许在查询执行阶段动态调节搜索精度。

我们可以创建一个使用 QBit 类型的列:

CREATE TABLE vectors (    id UInt64, name String, ...    vec QBit(BFloat16, 1536)) ORDER BY ();

并在查询时指定要参与计算的(最高有效)比特数量:

SELECT id, name FROM vectorsORDER BY L2DistanceTransposed(vector, target, 10)LIMIT 10;

Image

Query condition cache

查询条件缓存是在 ClickHouse 25.3 中引入的一项特性。它使 ClickHouse 能够记录数据 part 中哪些 granule 范围满足 WHERE 子句中的条件,并将这些信息作为一种临时索引,在后续查询中加以复用。

这一机制对于真实世界中的工作负载尤为有价值,例如仪表盘、告警系统或交互式分析场景。这类场景通常会反复对相同的数据(或如可观测性场景中那样不断增长的数据)应用相同的过滤条件(WHERE 条件)。

该缓存默认处于启用状态。在我们的实验中,它可以为查询性能带来一个数量级的提升。

我们在一个包含 1 亿行数据的 BlueSky 数据集上,分别在启用和未启用查询条件缓存的情况下执行了如下查询:

SELECT count()FROM blueskyWHERE    data.kind = 'commit'    AND data.commit.operation = 'create'    AND data.commit.collection = 'app.bsky.feed.post'    AND data.commit.record.text LIKE '%????%'

首次运行时,查询耗时为 0.481 秒;而在启用查询条件缓存后的后续运行中,查询耗时约为 0.037 秒,速度提升超过 10 倍。

Image

Join reordering

ClickHouse 25.9 引入了一项许多用户期待已久的重要功能 —— 自动全局 Join 重排序。

现在,ClickHouse 可以对跨越数十张表的复杂 Join 图进行自动重排序,覆盖最常见的 Join 类型,包括 inner、left outer、right outer、cross、semi 以及 anti。自动全局 Join 重排序基于一个关键事实:当 Join 涉及两张以上表时,其执行顺序是具有关联性的。

全局 Join 重排序由以下两个新设置进行控制:

  • query_plan_optimize_join_order_limit —— 指定参与重排序的最大表数量。

  • allow_statistics_optimize —— 允许使用统计信息来优化 Join 的执行顺序。

我们在 TPC-H Join 基准测试中,对一个包含 6 张表 Join 的查询验证了该功能。结果显示,该查询的执行速度相比之前提升了约 1,450 倍,同时内存使用量减少了约 25 倍。

更多关于 Join 重排序的细节,可以参考 25.9 版本的发布博客文章。

Image

Lazy reading/materialization

ClickHouse 25.4 引入了惰性物化(lazy materialization)机制。该机制的核心思想是:不再一开始就读取列数据本身,而是先记录哪些数据需要被读取,只有在真正需要使用时才实际加载数据。

在查询执行流水线的后期阶段之前,列值可以在各个阶段中被传递和过滤,但不会参与任何计算。

我们在一个查询场景中验证了这一特性,该查询用于找出 Amazon 评论中获得最多 “有用” 投票的记录,并返回排名前 3 的评论,同时包含其标题、摘要以及完整文本内容。

SELECT helpful_votes, product_title, review_headline, review_bodyFROM amazon.amazon_reviewsORDER BY helpful_votes DESCLIMIT 3FORMAT Null;

在未启用惰性物化的情况下,该查询耗时 219 秒;而启用惰性物化后,查询时间仅为 0.14 秒。这意味着性能提升了 1,576 倍,同时 I/O 使用量减少了 40 倍,内存占用降低了 300 倍。

/END/

试用阿里云 ClickHouse企业版

轻松节省30%云资源成本?阿里云数据库ClickHouse 云原生架构全新升级,首次购买ClickHouse企业版计算和存储资源组合,首月消费不超过99.58元(包含最大16CCU+450G OSS用量)了解详情:https://t.aliyun.com/Kz5Z0q9G

图片
图片

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:[email protected]

图片图片