使用不同ClickHouse引擎创建表时行数异常问题求助
解决ClickHouse表创建时行数异常问题
问题原因分析
- ReplicatedMergeTree行数是预期3倍:该引擎仅负责数据复制与合并,不会自动去重。如果原表本身存在重复数据(或查询时从分布式表跨分片重复拉取数据),新表会完全保留这些重复行。
- ReplicatedReplacingMergeTree行数大幅减少:该引擎基于
ORDER BY子句的键进行去重,当多个行拥有相同的created_at值时,合并阶段只会保留最后一行(或指定版本的行),导致大量非重复行被误去重。
解决方案
1. 修正ORDER BY子句,明确去重依据
ReplacingMergeTree的去重逻辑完全依赖ORDER BY键,必须将**能唯一标识每行的字段(如主键id)**加入ORDER BY,避免因时间戳相同误去重:
CREATE TABLE IF NOT EXISTS new_data ENGINE = ReplicatedReplacingMergeTree('/clickhouse/fedor/tables/{shard}/subfolder/new_data', '{replica}') ORDER BY (id, created_at) -- 用唯一键+时间戳作为排序键 SETTINGS index_granularity = 8192, allow_nullable_key=TRUE AS SELECT * FROM table WHERE column IS NOT NULL
2. 查询阶段提前去重(针对原表存在重复的情况)
若原表本身有重复数据,可在SELECT阶段先完成去重再插入新表:
CREATE TABLE IF NOT EXISTS new_data ENGINE = ReplicatedReplacingMergeTree('/clickhouse/fedor/tables/{shard}/subfolder/new_data', '{replica}') ORDER BY (id, created_at) SETTINGS index_granularity = 8192, allow_nullable_key=TRUE AS SELECT DISTINCT * -- 先去重再插入 FROM table WHERE column IS NOT NULL
3. 避免分布式表跨分片重复拉取
如果原表是分布式表,创建新表时直接查询对应本地分片表(而非分布式表),确保每个分片仅处理自身数据:
CREATE TABLE IF NOT EXISTS new_data ENGINE = ReplicatedReplacingMergeTree('/clickhouse/fedor/tables/{shard}/subfolder/new_data', '{replica}') ORDER BY (id, created_at) SETTINGS index_granularity = 8192, allow_nullable_key=TRUE AS SELECT * FROM local_table -- 替换为原表的本地分片表 WHERE column IS NOT NULL
4. 验证去重效果
ReplacingMergeTree的去重操作在后台合并时触发,刚创建表后可能仍能看到重复行,可手动触发合并查看最终结果:
OPTIMIZE TABLE new_data FINAL
(注:生产环境频繁执行OPTIMIZE会影响性能,仅用于验证)
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

