向后不兼容的变更
查询和语法变更
IN运算符现在对Bool类型采用精确值语义:只有集合中的0和1才会匹配Bool值。此前,IN集合中大于255的数值会被错误地归为 true,因此SELECT CAST(1, 'Bool') IN (256)返回1。现在会正确返回0。#93115 (Ashrith Bandla) 。- 已修复
NOT运算符的优先级,使其符合 SQL 标准:NOT现在的绑定优先级低于IS NULL、BETWEEN、LIKE和算术运算符。例如,NOT (x) IS NULL现在会被解析为NOT (x IS NULL),而不是(NOT x) IS NULL。这可能会改变依赖此前 (非标准) 行为的查询结果。#97680 (Alexey Milovidov) 。 - 在
WITH表达式列表元素中,SELECT不再允许作为未加引号的标识符使用。#101059 (Aruj Bansal) 。 IN运算符现在会拒绝复合类型 (Tuple、Array、Map) 内部存在有损的Decimal转换,使其行为与顶层标量比较保持一致。此前,精度检查仅对顶层标量值生效:例如,CAST('33.3', 'Decimal64(1)') IN (33.33)会正确返回0,但CAST(['33.3'], 'Array(Decimal64(1))') IN ([33.33])却会错误地返回1。现在这两种情况都会正确返回0。#101812 (Nihal Z. Miaji) 。
数据类型变更
- 数据类型的序列化版本现在会传播到嵌套数据类型。例如,String 序列化版本
with_size_stream之前仅应用于顶层 String 列和 Tuple 元素;现在它会应用于任意嵌套类型中的任何 String 类型,例如 Array、Map、Variant 或 JSON。此行为由 MergeTree 设置propagate_types_serialization_versions_to_nested_types控制,该设置现已默认启用。此更改后,新创建的 parts 将无法被旧版本读取,但旧的 parts 仍可在新版本中读取。升级是安全的,但降级则不安全。#94859 (Pavel Kruglov). - 已修复
QBit二进制序列化的字节序,现在使用小端格式。#101378 (Raufs Dunamalijevs).
存储和索引变更
- 已修正普通投影的元数据,使具有多列排序键的投影能够被正确识别。#91352 (Amos Bird)。
- 已修复跳过索引文件未遵循
replace_long_file_name_to_hash设置的问题。该问题会导致“文件名过长”错误,并使长名称索引无法正常读取。现在,当跳过索引的文件名超过max_file_name_length时,会像列文件一样对其进行哈希处理。这一变更向后兼容 (新服务器可以读取旧 parts) ,但如果降级 (或在滚动升级期间使用旧服务器) ,则可能导致长名称索引被忽略。#97128 (Raúl Marín)。
已移除的功能
- 移除了
hypothesis跳过索引类型。这是一个鲜为人知的 Experimental 功能,实际用途有限。现在,使用INDEX ... TYPE hypothesis创建表会报错。#96874 (Alexey Milovidov) 。 - 移除了 Experimental 的
detectProgrammingLanguage函数。#99567 (Alexey Milovidov) 。
设置和配置变更
- 将
mysql_datatypes_support_level的默认值从空值更改为decimal,datetime64,date2Date32,从而默认启用将 MySQLDATE正确映射为Date32、将DECIMAL/NUMERIC映射为Decimal,以及将带精度的DATETIME/TIMESTAMP映射为DateTime64。此前,MySQLDATE列会被映射为Date,而Date无法表示 1970-01-01 之前的日期,因此会导致数据损坏。#97716 (Alexey Milovidov).
插入和去重变更
- 现在默认启用异步插入——ClickHouse 默认会将所有小型插入按批次处理。这由
compatibility设置控制:将compatibility设为低于 26.2 的版本会恢复此前的默认值false。异步插入可在多个级别开启或关闭:在 config 中的用户 profile、会话级别、查询级别,或 MergeTree 表级别。#97590 (Sema Checherinda) 。
系统表变更
- 恢复了
system.query_log中的skip_indexes列。#101018 (Alexey Milovidov).
其他破坏性变更
mergeTreeAnalyzeIndexes{,UUID}现在接受 part 名称数组,而不是正则表达式,因为正则表达式较慢 (Experimental 功能) 。#98474 (Azat Khuzhin).- H3 库已更新到 v4,这提高了长度、面积及其他指标计算的精度。此更改向后不兼容,因为新结果与之前的结果不同。#100348 (Alexey Milovidov).
- 更改了
Merge表处理虚拟列的方式。如果底层表包含_table或_database,则这些列会从存储中读取;否则会在读取步骤之后,通过表达式步骤进行填充。#101742 (Mikhail Artemenko).
新功能
函数
- 新增
naturalSortKey(s)函数,用于生成自然排序键。#90322 (Nazarii Piontko). - 新增
arrayAutocorrelation(arr [, max_lag])函数,用于计算数值数组在各个滞后值下的归一化自相关。支持整数、浮点数和 Decimal 数组类型。#94776 (Wenyu Chen). has()函数现已支持用于 JSON 类型检查路径是否存在,类似于Map。#96927 (DQ).- 新增
mergeTreeTextIndex(database, table, index)表函数,可直接从文本索引读取数据。它既可用于查看内部信息,也可用于基于文本索引数据执行聚合。#97003 (Anton Popov). - 新增
obfuscateQuerySQL 函数。#98305 (Xuewei Wang). - 新增
caseFoldUTF8和removeDiacriticsUTF8函数,用于 Unicode 大小写折叠和去除变音符号。#98973 (George Larionov). printf函数现在支持非常量格式字符串,允许根据列值为每一行使用不同的格式模式。#98991 (Yash).- 新增
highlight()函数,可将文本字符串中出现的搜索词用 HTML 标签包裹 (默认为<em>/</em>) 。支持 ASCII 不区分大小写匹配、自动合并重叠匹配,以及自定义起始/结束标签。#99131 (Peng). - 新增
normalizeUTF8NFKCCasefold字符串函数,用于执行 NFKC_Casefold Unicode 归一化,即将 NFKC 归一化与大小写折叠结合起来。#99276 (George Larionov). - 为全文索引和
tokens函数新增unicode_word分词器。它使用 Unicode 单词边界规则拆分文本:ASCII 单词可包含连接符字符 (下划线、冒号、点、单引号) ,而非 ASCII 的 Unicode 字符则会成为单字符标记。可配置停用词默认使用常见的 CJK 标点符号。#99357 (Amos Bird). - 新增
arrayTranspose函数,接收一个二维数组 (矩阵) 并将其转置。#101214 (Vitaly Baranov). - 新增用于短语搜索 (连续标记序列) 的
hasPhrase函数 (别名matchPhrase) 。搜索采用穷举方式,文本索引暂不支持。#101997 (Elmi Ahmadov). - 新增将
dotProduct作为向量相似度索引支持的距离函数。现在还会校验所有距离函数的排序方向,以避免静默产生错误结果。#102254 (Renzo). stem函数现在可以对String、FixedString、Array([Fixed]String)、Nullable、LowCardinality和Const列中的所有单词/标记进行词干提取。#99137 (Jimmy Aguilar Mena).stem函数现已不再是 Experimental 功能 (此前必须启用allow_experimental_nlp_functions) 。#102399 (Jimmy Aguilar Mena).- 新增了
JSONAllValues函数,该函数将JSON列中的所有值以Array(String)形式返回,这些值会按文本表示形式进行序列化,并按其路径名称排序。还为JSON列上JSONAllValues表达式新增了文本索引支持:当在JSONAllValues(json_column)上创建文本索引时,它会自动用于过滤针对JSON子列的查询 (例如json_column.key1 = 'value') 。#100730 (Anton Popov). - 为
EXTRACT操作符新增了与 PostgreSQL 兼容的单位:EPOCH、DOW、DOY、ISODOW、ISOYEAR、WEEK、CENTURY、DECADE和MILLENNIUM。同时还修复了EXTRACT(WEEK FROM date),此前它会抛出错误。#100274 (Alexey Milovidov). - 通过 parser sugar,为 SQL 标准
OVERLAY函数语法新增了支持。overlay函数本身已存在;此次新增的是对基于关键字的写法的支持,即使用PLACING、FROM和FOR作为分隔符。#101681 (Desel72). - 现在可以使用
+操作符将Date和Date32值与Time和Time64值相加,生成DateTime或DateTime64结果。例如,SELECT toDate('2024-01-15') + toTime('14:30:25')会返回2024-01-15 14:30:25。结果会在会话时区中计算,超出范围的结果会根据date_time_overflow_behavior设置进行处理。#102421 (Nihal Z. Miaji).
SQL 和查询功能
- 当参数类型为
Nullable且未指定时,其值现在默认为NULL。#93869 (Vikash Kumar). - ClickHouse 现在可在
SELECT查询中基于最小/最大统计信息裁剪整个 parts。#94140 (zoomxi). - 新增对 Materialized CTEs 的支持:在查询执行期间,CTE 只会计算一次,并将结果存储在临时表中。#94849 (Dmitry Novik).
- 某些函数现在可以在 SQL 中省略括号使用。#95949 (Aly Kafoury).
- 为
JSON类型新增了组合 subcolumn 语法json.@path。如果该路径对应的是 scalar,则返回其字面值并将其作为Dynamic;如果该路径对应的是嵌套对象,则返回该 sub-object 并将其作为Dynamic;如果该路径不存在,则返回NULL。#98788 (Pavel Kruglov). - 为 subquery 表达式新增了
SOMEkeyword,其行为与ANY完全一致。#99842 (Artem Kytkin). - 新增对
SET TIME ZONE 'tz'的支持,可作为SET session_timezone的别名使用。#99883 (phulv94). - 新增支持将 SQL 标准
VALUESclause 用作FROM中的表表达式,例如SELECT * FROM (VALUES (1, 'a'), (2, 'b')) AS t(id, val)。#100143 (Desel72). - 新增对带
TO范围限定符的 SQL 标准复合 interval 字面量的支持,例如INTERVAL '1:30' HOUR TO MINUTE;在内部会将其分解为多个 intervals 之和。#100453 (Desel72). - 为 ordered 模式和 unordered 模式新增了
SYSTEM FLUSH OBJECT STORAGE QUEUE db.table PATH 'x'命令。#100709 (Bharat Nallan).
表引擎和存储
- 为
Paimon表引擎新增了增量读取支持,并提供基于 Keeper 的快照进度跟踪,包括通过paimon_target_snapshot_id进行定向快照增量读取。#93655 (XiaoBinMu) 。 - 在
DatabaseReplicated中新增了对 auxiliary ZooKeeper 的支持。#95590 (RinChanNOW) 。 - 新增了对读取 Iceberg v3 纳秒级 timestamp 类型 (
timestamp_ns和timestamptz_ns) 的支持,映射为DateTime64(9)和DateTime64(9, 'UTC')。这使 ClickHouse 能够读取 schema 中包含这些类型的 Iceberg 数据;但这并不表示已完整支持 Iceberg v3,也不支持使用这些类型写入 Iceberg v3。#97132 (Dmitry Kovalev) 。 - 为 Iceberg 表新增了
ALTER TABLE ... EXECUTE expire_snapshots('<timestamp>')。#97904 (murphy-4o) 。 - 为 Parquet 元数据新增了一个 SLRU 缓存,无需仅为读取元数据而重复下载文件,从而提升读取性能。#98140 (Grant Holly) 。
- 为 JSON 列新增了 MergeTree 跳过索引支持,可将
JSONAllPaths与bloom_filter、tokenbf_v1、ngrambf_v1和text(倒排) 索引类型配合使用,从而能够根据每个粒度中存在的 JSON paths 集合跳过相应粒度。#98886 (Pavel Kruglov) 。 - 新增了
commit_order投影索引,可按插入顺序重组数据。#99004 (Mikhail Artemenko) 。 - 为 MergeTree 中的
Map列新增了 bucketed serialization (map_serialization_version = 'with_buckets') 。键会被拆分到基于哈希的桶中,因此读取单个键 (m['key']) 时只需读取一个桶,而不是整个列;根据 map 大小不同,单键 lookup 可获得 2–49 倍加速。桶的数量和分桶策略可通过新的 MergeTree settingsmap_serialization_version、max_buckets_in_map、map_buckets_strategy、map_buckets_coefficient和map_buckets_min_avg_size控制。设置map_serialization_version_for_zero_level_parts会为 insert 保留基础 serialization,以避免写入开销,而合并后的 parts 则使用桶。bucketed serialization 支持在mapKeys/mapValues上使用跳过索引,并且当桶可用时,optimize_functions_to_subcolumns会将m['key']重写为按键的 subcolumn 读取。#99200 (Pavel Kruglov) 。
插入与去重
- 在 squashing 过程中,
max_insert_block_size_rows、max_insert_block_size_bytes、min_insert_block_size_rows和min_insert_block_size_bytes引入了新的行为,由兼容性设置use_strict_insert_block_limits控制。#94207 (Kirill Kopnev).
设置与配置
- 新增
table_readonlyMergeTree 设置,可将表标记为只读,防止写入和修改。#97652 (Alexey Milovidov). - 新增
use_partition_pruning设置 (别名use_partition_key) 。将其设为false可禁用基于分区键的分区剪枝。#97888 (Nihal Z. Miaji). <protocols>中每个type=http条目现在都可以指定自定义<handlers>键,指向独立的<http_handlers_*>配置段,从而为每个端口启用不同的 HTTP 路由规则。#98414 (Amos Bird).- 新增两个 MergeTree 设置——
replicated_fetches_min_part_level和replicated_fetches_min_part_level_timeout_seconds——允许副本跳过从对等节点拉取新写入的 (尚未合并的) parts,从而在高强度摄取期间降低复制开销。#98625 (tanner-bruce). - 新增
restore_access_entities_with_current_grants服务器级设置。启用后,恢复出的用户/角色其授权将被限制在执行恢复的用户有权授予的范围内 (语义与GRANT CURRENT GRANTS相同) ,而不是因ACCESS_DENIED失败。#98795 (pufit). - 新增
max_skip_unavailable_shards_num和max_skip_unavailable_shards_ratio设置,用于限制启用skip_unavailable_shards时可被静默跳过的分片数量。如果不可用分片的数量或比例超过配置的阈值,则会抛出异常,而不是静默返回不完整的结果。#99369 (Alexey Milovidov). - 实现了基于归一化查询哈希的配额控制,以保护公共 ClickHouse 服务免受滥用。
NORMALIZED_QUERY_HASH现已支持作为配额键类型——每个唯一的归一化查询对应一个独立的配额 bucket,因此CREATE QUOTA q KEYED BY normalized_query_hash会分别跟踪每个不同的查询。QUERIES_PER_NORMALIZED_HASH现已支持作为配额资源类型——限制任意单个归一化查询在一个时间间隔内的最大执行次数,因此MAX queries_per_normalized_hash = 100可防止任何单个查询模式运行超过 100 次。#99586 (Alexey Milovidov). auto_statistics_typesMergeTree 设置现在默认值为minmax, uniq,因此会自动为新表中所有适用的列创建 minmax 和 uniq 统计信息。materialize_statistics_on_insert现在默认值为false,因此统计信息会在合并期间构建,而不是在写入时构建,从而降低写入开销。将materialize_statistics_on_insert = 1可恢复旧行为。#101275 (Han Fei).- 为 materialized view 依赖链新增
prefer_dependency_replicarefresh 设置,以减少跨副本复制延迟导致的数据缺失。#101591 (Seva Potapov).
身份验证
- 新增了按服务器配置的 LDAP 选项
<follow_referrals>(默认值为false) ,用于控制 LDAP 客户端是否跟随转介。禁用转介跟随可避免从 Active Directory 域根 base DN 开始搜索时出现超时和卡住的情况,并减少日志噪声。#96765 (paf91).
系统表
- 新增
system.histogram_metric_log系统表,该表会定期对所有直方图指标生成快照 (例如 S3/Azure 延迟、Keeper 请求处理阶段耗时) 。system.histogram_metrics的value列现为Float64,以提供更高的灵活性并更好地兼容 Prometheus 数据模型。#103046 (Miсhael Stetsyuk) 。
Experimental 功能
- 新增了 ALP 浮点压缩编解码器 (对于不可压缩的 double,不支持回退到 ALP_rd) 。#91362 (Nazarii Piontko) 。
- 为 JSON 列新增了 Experimental 惰性类型提示。通过
allow_experimental_json_lazy_type_hints启用后,如果ALTER TABLE ... MODIFY COLUMN json JSON(path TypeName)仅添加或修改类型提示,则会作为纯元数据操作立即完成,无需重写历史数据。对于旧的 parts,类型提示会在查询时应用;在 INSERT 和后台合并期间则会被 materialized。#97412 (tanner-bruce) 。 - 新增了通过
polyglot库支持外部 SQL 方言的功能。#99496 (Alexey Milovidov) 。 - 新增了
query_plan_optimize_join_order_randomize设置,该设置会将用于 join 重排序的统计信息随机化,可用于测试。#100643 (Vladimir Cherkasov) 。 - ClickHouse 新增了 AI 函数支持,允许用户使用 SQL 调用 OpenAI 和 Anthropic 端点。
aiGenerate是首个此类函数。#100831 (George Larionov) 。 - 新增了 AI 函数
aiClassify、aiExtract和aiTranslate,用于在 ClickHouse 中调用 LLM API。#100832 (George Larionov) 。 - 新增了基于 Azure 和 Delta Kernel 的数据湖支持。#102202 (Smita Kulkarni) 。
性能提升
JOIN 性能
- 对
HashJoin和ConcurrentHashJoin进行了一些小幅优化。#96663 (Yarik Briukhovetskyi). - 新增支持基于优化器统计信息交换
ANTI、SEMI和FULLJOIN 的两侧。#97498 (Hechem Selmi). - 通过在写入前检查
JoinUsedFlags是否已设置,减少了RIGHT和FULLJOIN 中的缓存争用。#99274 (Hechem Selmi). - 通过使用直接索引哈希表,加快了对键范围较小的
Int32和Int64执行哈希 JOIN 的速度。#99275 (Hechem Selmi).
查询优化
- 优化了大型多边形场景下
pointInPolygon的粒度跳过,并修复了pointInPolygon在主键剪枝期间进行索引分析时会抛出异常的问题。#91633 (Nihal Z. Miaji). - 现在读取 projections 时会遵循
optimize_read_in_order设置。#95885 (Andrey Zvonov). - 略微优化了从文本索引字典读取数据的过程,提升了文本索引分析的整体性能。#97519 (Anton Popov).
- 提升了同时包含已索引列和未索引列的组合条件查询在文本索引分析方面的性能。此前,在这种情况下,索引分析期间的提前退出优化会被错误地禁用。#98096 (Anton Popov).
- 提升了包含会生成超长 Array 或 Map 的常量表达式查询的性能。#98287 (Alexey Milovidov).
- 修复了
DateTime64主键与整数常量比较时的键条件分析问题,此前这会导致无法进行粒度剪枝。#98410 (Amos Bird). - 设置
optimize_syntax_fuse_functions现已默认启用。#98424 (Alexey Milovidov). - 当谓词包含任意比较运算符 (
=,<,>,!=) ,且分区键被包裹在确定性函数链中时,现在允许进行分区剪枝 (例如,在PARTITION BY x的情况下,cityHash64(x) % 5 > 2、toYYYYMM(x) < 2026、toYYYYMM(x) = 2026或toYYYYMM(x) != 2026这类谓词现在都可以使用分区键进行剪枝) 。#98432 (Nihal Z. Miaji). - 当
CAST的目标类型为Nullable且转换具有单调性时,现在允许使用按序读取优化和主键剪枝;例如,在PRIMARY KEY x的情况下,ClickHouse 现在可以对ORDER BY x::Nullable(UInt64)使用按序读取优化,并对WHERE x::Nullable(UInt64) > 500000这类谓词使用主键剪枝。#98482 (Nihal Z. Miaji). - 当整型列与浮点数字面量比较时,现在允许进行索引剪枝和过滤器下推;例如,
WHERE x < 10.5这类谓词现在可以使用主键进行剪枝,而prime < 1e9或number < 1e5这类过滤条件现在也会下推到primes()和numbers()表函数,而不是导致无界执行。#98516 (Nihal Z. Miaji). - 对于使用字面量字符串 Regex 交替模式 (如
^(abc-1|abc-2)) 过滤 MergeTree 主键列的查询,现在当这些备选项具有共同前缀时,可以使用主键剪枝。#98988 (Yash). - 优化了
INTERSECT ALL和EXCEPT ALL。#99097 (Raufs Dunamalijevs). - 新增了对反向顺序读取使用
read_in_order_use_virtual_row优化的支持。#99198 (Vladimir Cherkasov). - 使用单个字典的
LowCardinality列执行非连续查询时速度更快。#99285 (Ivan Babrou). - 修复了多核机器上带聚合的短查询出现负向扩缩容的问题。当查询仅读取少量标记时,聚合后管道不再扩展到
max_threads,从而避免了大多数为空的流带来的额外开销。#99493 (Alexey Milovidov). - 通过正确选择读取任务大小,提升了使用并行副本的查询性能。#99801 (Nikita Taranov).
- 当
ORDER BY前缀已覆盖所有GROUP BY键时,移除了尾部多余的ORDER BY元素。#100157 (Alexey Milovidov). - 通过将
LIMIT子句下推到UNION ALL中,优化了查询。#100364 (Alexey Milovidov). - 为
ORDER BY中String和FixedString列的比较添加了 JIT 编译支持,使字符串占比较高的排序键在合并阶段的排序性能提升了 6–17%。#100577 (Raúl Marín). - 当启用
read_in_order_use_virtual_row且同时启用新的read_in_order_use_virtual_row_per_block设置时,现在会在从 MergeTree 读取每个块后输出虚拟行边界信息,从而允许在流处理中途重新调整数据被WHERE/PREWHERE/JOIN完全过滤掉的 parts 对应 source 的优先级。#100603 (Vladimir Cherkasov). - 改进了通过并行副本执行的简单视图 (基于底层 MergeTree 表) 查询的并行化效果。#100815 (Igor Nikonov).
- 当
parallel_replicas_allow_view_over_mergetree=1时,新增了对简单视图上并行副本的支持 (包括基于MergeTree表且符合条件的UNION ALL视图) 。这会并行化视图的外层查询而非内层查询,从而提升跨节点的查询并行度。#100958 (Igor Nikonov). - 当查询计划中存在带
IN的过滤器时,优化了full_sorting_merge按主键顺序读取的性能。#101261 (Nikita Taranov). - 改进了
Map、Array和Tuple列在以转义字符串形式传递值时 (例如'{\'key\':1}') 的INSERT VALUES性能,避免了不必要地回退到 SQL 表达式解析器。#102119 (Joanna Hulboj).
函数与聚合性能
- 提升了
levenshteinDistance函数的性能。#94543 (Joanna Hulboj). - 通过避免逐元素函数调用,优化了批次 decimal 类型转换的性能。#95923 (Konstantin Bogdanov).
- 提升了
LIKE查询的性能。#98149 (Elmi Ahmadov). - 通过使用本地累加器,避免按行经由 aggregate state 进行 store-forwarding,优化了
avgWeightedaggregate function;对于Nullable输入,性能最高提升 27%。#98793 (Antonio Andelic). - 通过对内部循环去虚拟化,加快了
Float64列上var*Stable和stddev*Stable函数的执行速度。这使编译器能够应用优化 (FMA/寄存器) ,但会在 ULP 级别改变浮点结果。#99460 (Riyane El Qoqui). - 对于 32/64 字节输入,使用优化后的 Firedancer base58 编码 (对
base58Encode自动生效) ;如果解码结果为 32/64 字节,也可使用优化后的 base58 解码 (需显式调用base58Decode('...', 32)) 。#99461 (Joanna Hulboj). - 通过消除不必要的内存移位,优化了
cutURLParameter函数。#100218 (Nikita Semenov). - 通过为
itoa快速路径扩展与 dragonbox 兼容的舍入机制,加快了大整数值的浮点数到字符串转换。#100649 (Raúl Marín). - 用 zmij 替换 dragonbox,将浮点数到字符串的转换速度提升了 1.5 倍到 3 倍。#100650 (Raúl Marín).
- 通过用 Barrett reduction 替代软件除法并展开转换循环,加快了
Int128/UInt128到字符串的转换。#100671 (Raúl Marín). - 避免了在
UniqExactSet并行合并期间创建冗余线程。#100686 (Jiebin Sun). - 为
UniqExactSet新增了批次并行合并。#100687 (Jiebin Sun).
存储与 I/O 性能
- 降低了在带有已完成变更的 ReplicatedMergeTree 表上执行只读操作时的锁竞争。#95771 (Eduard Karacharov).
- Iceberg 现在支持异步将元数据预先加载到缓存中,可在建表时通过设置
iceberg_metadata_async_prefetch_period_ms启用。针对 Iceberg 表的SELECT查询现在还可以指定iceberg_metadata_staleness_ms参数:如果缓存中的元数据比指定的 staleness 值更新,ClickHouse 就会使用缓存中的元数据版本;否则会查询远程 Iceberg catalog 获取最新元数据。这可以避免在请求处理期间调用 Iceberg catalog,从而带来明显的性能提升。#96191 (Arsen Muk). - S3Queue 的 ordered 模式现在使用 S3
ListObjectsV2StartAfter来避免重新列出整个前缀的历史内容,从而减少ListObjects调用。#96370 (Venkata Vineel). - 为 YTsaurus 表引擎启用了并行读取。#97343 (MikhailBurdukov).
- 提升了数据湖的性能。在之前的版本中,从对象存储读取时不会将管道调整到与处理线程数匹配。#99548 (Alexey Milovidov).
- 现在支持在通过用户态页缓存读取远程文件时进行预取。#99919 (Alexey Milovidov).
- 修复了在
deduplicate_insert=enable(自 26.2 起默认启用) 时明显的 INSERT 性能回退问题:将数据哈希计算从 squashing 阶段延后到 sink 端,并通过updateHashWithValueRange按批次对列进行哈希,使 22 列、500 万行数据的开销从约 ~2.5s 降至 ~0.5s。#101494 (Sema Checherinda).
内存优化
- 对于同步插入,现在可以省略原始块 (去重所需) ,以节省内存。#96661 (Sema Checherinda).
- 在某些场景下,并行窗口函数以及处理大型数组的
arrayFold工作负载的性能有所提升,内存占用也有所降低。这还可以减轻缺页压力,并在内存限制较紧时提高相关查询的稳定性。#98892 (filimonov).
改进
查询与 SQL
- 现在已在视图中正确支持聚合 projections。#88798 (Amos Bird).
optimize_aggregators_of_group_by_keys现在能够正确优化GROUPING SETS查询中的 aggregate functions。#93935 (Xiaozhe Yu).- 新增了在
join_use_nulls启用时将OUTERjoin 优化为INNERjoin 的支持。#95968 (Vladimir Cherkasov). - 扩展了
cast_keep_nullable,使其可用于Dynamic/JSON类型。启用后,将来自可为Nullable的类型的NULL转换时会返回NULL;否则,NULL会抛出CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN错误。#96504 (Seva Potapov). - 为
CREATE USER添加了ROLEclause。#97074 (Vitaly Baranov). - 在
EXPLAIN查询输出中,将延迟过滤器的信息作为单独条目显示 (在使用行策略/PREWHERE 和 FINAL 时) 。#97374 (Yarik Briukhovetskyi). - 新增了对
FROMclause 中带括号的表 join 表达式的支持,例如SELECT * FROM (t1 CROSS JOIN t2)。#97650 (Alexey Milovidov). - 在分布式索引分析期间应用数据跳过索引。#97767 (Azat Khuzhin).
- 表的 sorting key 现在可以是类似
toDate(time)这样的表达式,并且当这类表达式属于 filters 的一部分时,是否不延迟处理它们的决定也会一并作出。#98237 (Yarik Briukhovetskyi). - JOIN 顺序优化器现在会根据现有 join 条件推断传递性的等值 join 谓词。例如,给定
A.x = B.x AND B.x = C.x,会识别出等价关系A.x = C.x,从而允许优化器考虑在通过传递关系相连的表之间进行 direct joins。这可以提升星型和雪花 schema 的执行计划质量。该功能由新的enable_join_transitive_predicatessetting 控制 (默认关闭) 。#98479 (Alexander Gololobov). - 当启用
apply_row_policy_after_final或apply_prewhere_after_final时,现在会分解行策略和PREWHERE中复合的AND条件,以提取 sorting-key 原子条件用于主键索引分析。此前,如果延迟过滤器中同时包含 sorting-key 和非 sorting-key 谓词 (例如x > 1 AND y != 'foo') ,整个表达式都会被排除在索引分析之外。#98513 (Yarik Briukhovetskyi). - 现在只有“存活”的 (即可连接的) 副本会参与分布式索引分析。#98521 (Azat Khuzhin).
- 自动并行副本启发式中使用的节点数量现已限制为 cluster 中的实际节点数 (而不再只看
max_parallel_replicassetting) 。#98668 (Nikita Taranov). - 为分布式索引分析实现了对冲请求和异步读取。#98724 (Azat Khuzhin).
- 在分布式索引分析中新增了对
SAMPLE子句的支持。#98931 (Azat Khuzhin). - 为 multiply 增加了单调性支持,从而可对
key * constant表达式启用主键剪枝。#98983 (Amos Bird). - analyzer 的错误消息不再转储表中的所有列 (这可能会产生超过 150KB 的异常信息) 。现在列列表最多只显示 10 项。#99002 (Yash).
- 现在可以正确返回包含 joins 的子查询中的列统计信息,以便父查询将其用于 join 重排序。#99096 (Alexander Gololobov).
- 现在允许在不指定列类型的情况下使用
ALTER TABLE MODIFY COLUMN x TTL ...。#99208 (Nikolay Degterinsky). - 改进了
EXPLAIN PLAN pretty=1的输出:打印顶层查询的输出列,显示 join relation 的标记/符号以及预估结果行数和局部性,并为 join/source 步骤包含各步骤的输出列。#99462 (Kirill Kopnev). - 修复了
merge()table function 在查询并非所有底层 distributed/remote 表中都存在的列时,因UNKNOWN_IDENTIFIER错误而失败的问题。#99833 (Alexey Milovidov). - 当条件不是 CNF 时,优化器不再使用
ConditionSelectivityEstimator(例如where a = 0,这是一个单一条件,统计信息对此无能为力) 。#100110 (Han Fei). - 在分区剪枝之后应用
distributed_index_analysis_min_indexes_bytes_to_activate。#100477 (Azat Khuzhin). EXPLAIN PIPELINE现在支持distributed=1设置,以包含远程管道片段。#100513 (Nikita Taranov).use_partition_pruning = 0现在除了禁用基于分区键的剪枝外,还会禁用MinMax索引剪枝以及分区键列上的计数优化。#100904 (Nihal Z. Miaji).EXPLAIN [PLAN] pretty=1现在会以人类可读的格式打印表达式。#100927 (Kirill Kopnev).accurateCastOrNull和accurateCastOrDefault现在支持Tuple目标类型,包括元素为Nullable的嵌套Tuples。此前这些函数会拒绝Tuple目标类型,因为Tuple不能位于Nullable内部。#100942 (Nihal Z. Miaji).- 现在可以在
WITH子句中、SELECT查询之前使用尾随逗号。#101093 (Aruj Bansal). - 当谓词具有足够高的选择性时,已为带 FINAL 的 ReplacingMergeTree 实现惰性列物化。#101647 (Nikolai Kochetov).
- 改进了无统计信息条件的默认选择性估算,使其符合业界通用启发式规则:
LIKE条件的选择性为 0.1,未知条件的选择性为 0.33。#101653 (Alexander Gololobov). - 在查询树中内联 VIEW 子查询,以便对 VIEW 应用更多优化。#100830 (Dmitry Novik).
函数
- 现在,
JSONExtract函数支持使用原生 JSON/Object 作为输入。#96711 (Fisnik Kastrati) 。 - 引入了
tokensForLikePatternSQL 函数,该函数会对LIKE模式进行分词,同时保留通配符语义:%和_被视为通配符,转义后的通配符 (\%、\_) 被视为字面量,而与未转义通配符相邻的标记会被丢弃。#97872 (Amos Bird) 。 - 实现了
toDaysInMonth()函数,该函数返回指定日期所在月份的天数。#99227 (Vitaly Baranov) 。 - 将
unicodeWord分词器重命名为asciiCJK。#100956 (George Larionov) 。 - 为 SQL 标准
OVERLAY函数语法添加了解析器层面的语法糖。overlay函数已存在;此次新增了对基于关键字形式的支持,使用PLACING、FROM和FOR作为分隔符。#101681 (Desel72) 。 ngrams函数现在会拒绝无效的 ngram 长度。例如,SELECT ngrams('abc', 0)现在会返回错误。#101922 (Robert Schulze) 。- 在
LIKE优化中新增了对array分词器的支持。#102880 (Elmi Ahmadov) 。
表引擎和存储
- 为 MergeTree 新增了专用清理线程,以防止在高合并负载下出现清理延迟。#91574 (Amos Bird).
- 带有
DELETE TTL规则的表现在可以使用垂直合并算法。#97332 (murphy-4o). - 启用
prewarm_mark_cache设置后,次级索引的标记现在也会被预热 (会在数据分区片段 fetch 期间以及表启动时加载到 index mark cache 中) 。#97772 (Anton Popov). - 现在可以在
Nullable([Fixed]String)和Array(Nullable([Fixed]String))列上构建文本索引。#98118 (Jimmy Aguilar Mena). - 对于普通 shared merge tree,现在会在
DROP DATABASE期间提前取消后台合并。#98161 (Shaohua Wang). - 新增了
finalize_projection_parts_synchronously设置,允许在 INSERT 期间同步完成 projection parts 的最终处理,从而降低具有大量 projections 的表的峰值内存占用,同时默认保留现有的异步行为。#98228 (Amos Bird). - 新增了
share_nested_offsetsMergeTree setting (默认值为true) 。当设置为false时,带点号名称的 Array 列 (例如n.a、n.b) 会被视为独立列,而不再像旧版 Nested 语义那样共享 offset 文件并校验数组大小是否相等。#98416 (Amos Bird). - 通过并行预先取消合并,优化了
TRUNCATE DATABASE TABLES LIKE。#98597 (Shaohua Wang). - 通过在不获取锁的情况下释放任务资源,减少了
MergeTreeBackgroundExecutor中的锁竞争。#98604 (Dmitry Novik). TRUNCATE DATABASE现在支持响应查询取消。#98828 (Shaohua Wang).- 在更改 merge tree setting 后,会重启 statistics cache。#98520 (Han Fei).
- 新增了
compress_per_column_in_compact_partsMergeTree setting,用于控制压缩后块在 Compact parts 中的组织方式。当为true(默认值,保留当前行为) 时,每列都会开启一个新的压缩块,从而支持选择性解压。当为false时,一个粒度内的所有列都会打包到同一个压缩块中,从而提升始终读取所有列的 workloads 的压缩率和读取性能。#101114 (Amos Bird). - 文本索引现已 GA,并且无论
compatibility设置如何都会保持启用,从而避免在备份恢复期间或在兼容模式下运行时被异常禁用。#101518 (Nikita Fomichev). - 新增了对基于
mapValues(map)构建的文本索引配合IN运算符使用的支持。#99286 (Anton Popov). - 改进了对同一查询中同时使用多个文本索引的分析。文本索引的直接读取优化不再需要
use_skip_indexes_on_data_read设置。#102255 (Anton Popov). - 通过
HINT模式,为hasPhrase函数增加了文本索引分析支持。#102438 (Elmi Ahmadov). - MinMax 列统计信息现在将最小值和最大值存储为
Field(带类型) ,而不是Float64。序列化格式会连同这些值一起包含列类型名称。统计信息文件版本已升级到 V2;由旧版本写入的文件需要重新物化 (ALTER TABLE ... MATERIALIZE STATISTICS ALL) 。#100605 (Han Fei).
数据湖
- 新增了一个用于检查
DataLakeCatalog健康状态的查询。#94690 (Smita Kulkarni). - 改进了 Unity Catalog 的 Iceberg 写入功能。#98162 (Konstantin Vedernikov).
- 重构了
IcebergManifestFile中的实体,以降低代码维护过程中出错的可能性 (同时也修复了一些 manifest 文件缓存问题) 。#98231 (Daniil Ivanik). - 增强了 Iceberg
ALTER TABLE ... EXECUTE expire_snapshots(...),支持更丰富的参数。#99130 (murphy-4o). - 调整了 Iceberg 通过 catalog 执行 insert 时的接口。已弃用
storage_catalog_type、storage_aws_access_key_id及类似设置。#100334 (Konstantin Vedernikov). - 修复了 Iceberg 中因混用存储路径和元数据路径而导致的路径处理不一致问题;强制要求 Iceberg 表写入的表位置必须为 URL 或绝对路径;为 Azure 中的文件大小统计添加了回退机制;以兼容 Spark 的方式处理了
version-hint.txt;引入了类型级抽象,以降低混淆路径类型的可能性;并修复了 position deletes 的使用问题。#100420 (Daniil Ivanik). - 当禁用
show_data_lake_catalogs_in_system_tables时,避免为了 “Maybe you meant …” 表提示而扫描整个远程数据湖 catalog。#100452 (Alsu Giliazova). - 现在,用于解析 Iceberg 数据文件的对象信息包含从 manifest 文件中解析出的文件行数以及以字节为单位的文件大小。#100645 (Daniil Ivanik).
- 新增了支持虚拟列的 Delta Lake 剪枝器。#101634 (Konstantin Vedernikov).
S3 和对象存储
- 为 S3 表引擎新增了一个
{_schema_hash}占位符,用于将表列定义的哈希值插入到 S3 路径中。#98265 (Miсhael Stetsyuk) 。 - 新增了一个选项,用于强制 S3 端点使用 virtual/path 风格。#102378 (Konstantin Vedernikov) 。
设置与配置
- 用户现在可以在
users_xml配置中指定多种身份验证方法。#91998 (Flip-Liquid). - 现在可以为由 Replicated database 创建的 cluster 设置
internal_replication配置项。#97228 (Pervakov Grigorii). - 新增
allow_nullable_tuple_in_extracted_subcolumns配置项,用于控制从Tuple、Variant、Dynamic和JSON中提取的Tuple(...)subcolumns 是返回为Nullable(Tuple(...))(缺失行返回NULL) ,还是返回为Tuple(...)(缺失行返回默认 tuple 值) 。默认禁用;只能通过重启 server 更改。#97299 (Nihal Z. Miaji). type_json_allow_duplicated_key_with_literal_and_nested_object现已默认启用,从而避免在解析诸如{"a" : 42, "a" : {"b" : 42}}这样的 JSON 时出现重复键错误,而 ClickHouse 可能会根据原始数据{"a" : 42, "a.b" : 42}生成这类 JSON。#97423 (Pavel Kruglov).- 列统计信息现已 GA。配置项
allow_experimental_statistics(默认值为false) 已废弃,改用allow_statistics(默认值为true) ;allow_statistics_optimize已从 beta 升级为 GA;ClickHouse 会为新列创建minmax和uniq统计信息 (MergeTree settingauto_statistics_types) ;另外,为避免 INSERT 变慢,materialize_statistics_on_insert现在默认禁用。#97487 (Han Fei). - 进一步澄清了
enable_parallel_replicas与automatic_parallel_replicas_mode之间的关系:只有当enable_parallel_replicas > 0时,查询才能使用并行副本。automatic_parallel_replicas_mode=1时,系统会在规划阶段根据已收集的统计信息作出决策;automatic_parallel_replicas_mode=0时,则会对所有受支持的查询使用并行副本,而不考虑统计信息。使用并行副本的 Distributed insert-select 始终等同于automatic_parallel_replicas_mode=0。#97517 (Nikita Taranov). - 默认启用了 impersonate 功能 (EXECUTE AS target_user) 。#97870 (Vitaly Baranov).
- 新增
access_control_improvements.disallow_config_defined_profiles_for_sql_defined_users配置项 (默认允许) ,禁止 SQL 定义的用户使用由 config 定义的 settings profiles (defaultprofile 除外) 。#98662 (Alexander Tokmakov). - 新增一个配置项,用于控制
Variant和Dynamic发生类型不匹配时的行为 (throw 或返回 null) 。#99085 (Bharat Nallan). - 将 Executable UDFs 的默认
stderr_reaction从throw改为log_last。向 stderr 写入警告的 UDFs 在退出码为 0 时不再失败,且现在退出码异常会包含 stderr 内容。#99232 (Xu Jia). - 新增
input_format_column_name_matching_mode配置项,允许为 input formats 设置不同的大小写敏感性。#99346 (manerone). - 系统表不再默认启用自动统计信息,因为它们很少能从中受益。#102862 (Han Fei).
系统表和监控
- 查询执行期间使用的数据跳过索引现可在
system.query_log新增的skip_indices列中查看。#99793 (Grant Holly) 。 system.part_log新增了projections_duration_ms列,用于记录每个 projection 的合并/重建耗时 (毫秒) 。#98292 (Amos Bird) 。information_schema.tables新增了列别名INDEX_LENGTH。#101705 (Robert Schulze) 。information_schema.tables现在会忽略非活动的 table parts,因此显示的表大小值更加贴近实际。#101706 (Robert Schulze) 。
ClickHouse Keeper
find_super_nodes不再卡在遍历第一个超级节点的子节点上,因此现在可以找到多个超级节点。#97819 (pufit).- 在开始终结时立即将 ZooKeeper 会话标记为已过期,而不是等待发送线程退出。这样一来,其他线程无需等待即可建立新会话。#99102 (Raúl Marín).
- 跳过已断开会话的失效 Keeper 请求,避免不必要的 Raft 往返。被跟踪的已结束会话数量由
max_finished_sessions_cache_size协调设置限制。#99246 (Antonio Andelic). - 防止 Keeper 的
mntr命令因锁竞争而阻塞。#99472 (Antonio Andelic). - 通过在互斥锁作用域外调用回调函数并分发读取请求,降低了 Keeper 分发器中的锁竞争,并新增了带性能分析的锁保护以增强可观测性。#99751 (Antonio Andelic).
内存管理
- 新增了
use_separate_cache_arena配置参数,用于控制是否分离缓存 Arena。#100664 (Seva Potapov).
数据格式
- 新增
output_format_trim_fixed_string设置,用于在文本输出格式中去除FixedString值末尾的空字节。 #97558 (NeedmeFordev). - 现在可以解析同一列中包含不同 Geo 类型的 GeoParquet 文件。 #97851 (Mark Needham).
- 二进制
AggregateFunction状态的反序列化现在要求完整读取输入内容。如果存在多余的尾随字节,ClickHouse 将抛出异常,而不再接受格式错误的状态数据。 #98786 (Nihal Z. Miaji). - 用户现在可以将 ClickHouse 时间间隔数据类型写入 Arrow 格式。 #99519 (Peter Nguyen).
- 新增了对在 Arrow 和 Parquet 格式中导入和导出 UUID 数据类型的原生支持,可自动推断顶层 UUID 的逻辑类型,并支持为嵌套 UUID 显式提供 schema 提示。 #99521 (Ivan).
- 允许 Parquet 文件最后一个块的末尾缺少填充。 #99857 (Seva Potapov).
- 现在,通过 Arrow 编码器将 UUID 导出到 Parquet 时会包含正确的 UUID 类型注解,因此在回读这些文件时无需再手动转换
FixedString(16)数据。 #100150 (Ivan). - 新增了对将 Apache Arrow
StringView和BinaryView数据类型原生导入 ClickHouseString列的支持,提升了基于 Arrow 的摄取兼容性。 #100762 (Ivan). - 在
Arrow、ArrowStream、ORC和旧版Parquet格式中新增了对Nullable(Tuple)的支持。 #101272 (Nihal Z. Miaji).
命名集合与字典
- 在 PostgreSQL 字典源允许的键中新增了
sslmode,从而可以为 PostgreSQL 字典连接配置 SSL 模式 (例如 AWS RDS,其默认强制使用 SSL) 。#98014 (mcalfin). - 避免删除作为字典源依赖项的命名集合。#98127 (Pablo Marcos).
- 新增了对
Map和JSON/Object类型作为字典属性的支持。字典现在可以在 FLAT 和 HASHED 布局中存储和检索复杂类型,包括Map(String, String)、Map(String, Array(String))、JSON和Nullable(JSON)。#98627 (yanglongwei). SYSTEM RELOAD DICTIONARIES现在会按拓扑顺序重新加载字典,这样以其他字典为源的字典在重新加载后就能获取最新数据。#98356 (Alexey Milovidov).- 缓存字典在
hasKeys中不再获取排他锁,而是通过在缓存读取时使用共享锁来减少锁竞争。#100796 (liuguangliang).
其他改进
- 除非用户有权显示所有必需的列,否则
ACCESS_DENIED提示将不再泄露列名;数据库名和表名在提示中仍然可见。#91067 (filimonov). - 现在仅当本地服务器主机名对应的 IP 发生变化时,才会重新加载集群配置,而不是在任意主机的 IP 发生变化时重新加载。#93726 (Zhigao Hong).
- 在发生崩溃时刷新异步日志缓冲区。#97836 (Azat Khuzhin).
- 减少了访问控制期间的锁争用。#97894 (Nikita Taranov).
- 将 ClickStack 更新至版本 2.20.0。#98252 (Aaron Knudtson).
- 在嵌入式客户端 (SSH 和 WebSocket 协议) 中禁用 AI SQL generation (
??命令) ,以防止访问服务器环境变量。#100290 (Alexey Milovidov). - 在使用 RabbitMQ 存储时,对损坏的消息返回 NACK。#102157 (Seva Potapov).
缺陷修复
全部缺陷修复(点击展开)
全部缺陷修复(点击展开)