跳转到主要内容

即时变更

启用即时变更后,更新的行会立即被标记为已更新,后续的 SELECT 查询将自动返回变更后的值。未启用即时变更时,你可能需要等待后台进程完成这些变更后,才能看到变更后的值。 对于 MergeTree 家族的表,可以通过启用查询级设置 apply_mutations_on_fly 来开启即时变更。
SET apply_mutations_on_fly = 1;

示例

我们来创建一个表,并执行一些变更操作:
CREATE TABLE test_on_fly_mutations (id UInt64, v String)
ENGINE = MergeTree ORDER BY id;

-- 禁用变更的后台物化,以展示
-- 未启用即时变更时的默认行为
SYSTEM STOP MERGES test_on_fly_mutations;
SET mutations_sync = 0;

-- 向新表中插入若干行
INSERT INTO test_on_fly_mutations VALUES (1, 'a'), (2, 'b'), (3, 'c');

-- 更新行的值
ALTER TABLE test_on_fly_mutations UPDATE v = 'd' WHERE id = 1;
ALTER TABLE test_on_fly_mutations DELETE WHERE v = 'd';
ALTER TABLE test_on_fly_mutations UPDATE v = 'e' WHERE id = 2;
ALTER TABLE test_on_fly_mutations DELETE WHERE v = 'e';
我们通过一个 SELECT 查询来检查更新结果:
-- 显式禁用即时变更
SET apply_mutations_on_fly = 0;

SELECT id, v FROM test_on_fly_mutations ORDER BY id;
请注意:当我们查询新表时,这些行的值尚未更新。
┌─id─┬─v─┐
│  1 │ a │
│  2 │ b │
│  3 │ c │
└────┴───┘
下面来看看启用即时变更后会发生什么:
-- 启用即时变更
SET apply_mutations_on_fly = 1;

SELECT id, v FROM test_on_fly_mutations ORDER BY id;
现在,SELECT 查询会立即返回正确结果,无需等待变更生效:
┌─id─┬─v─┐
│  3 │ c │
└────┴───┘

性能影响

启用即时变更后,变更不会立即物化,而只会在 SELECT 查询时应用。不过请注意,变更仍会在后台异步物化,而这一过程开销较大。 如果在一段时间内,已提交的变更数量持续超过后台处理的变更数量,那么待应用的未物化变更队列就会不断增长。最终,这将导致 SELECT 查询性能下降。 我们建议将设置 apply_mutations_on_fly 与其他 MergeTree 级别的设置 (如 number_of_mutations_to_thrownumber_of_mutations_to_delay) 一并启用,以限制未物化变更队列无限增长。

对子查询和非确定性函数的支持

即时变更对包含子查询和非确定性函数的场景支持有限。仅支持结果大小适中的标量子查询 (由设置 mutations_max_literal_size_to_replace 控制) 。仅支持常量型非确定性函数 (例如函数 now()) 。 这些行为由以下设置控制:
  • mutations_execute_nondeterministic_on_initiator - 如果为 true,则在发起副本上执行非确定性函数,并在 UPDATEDELETE 查询中将其替换为字面量。默认值:false
  • mutations_execute_subqueries_on_initiator - 如果为 true,则在发起副本上执行标量子查询,并在 UPDATEDELETE 查询中将其替换为字面量。默认值:false
  • mutations_max_literal_size_to_replace - 在 UPDATEDELETE 查询中可替换的序列化字面量的最大大小 (以字节为单位) 。默认值:16384 (16 KiB) 。
最后修改于 2026年6月10日