ClickHouse 写入是什么
ClickHouse 写入用 INSERT INTO 语句:可以接 VALUES 常量、SELECT 子查询,或用 FORMAT 指定外部数据格式。每次 INSERT 都会生成一个独立的 data part,part 越多后台合并压力越大,因此写入方式讲究攒批而不是逐行。Atomic 数据库下的表对相同数据块的重复写入默认做幂等去重,重试导入前先理解这一行为。
基本信息
| 语法 | INSERT INTO t [(cols)] VALUES / SELECT / FORMAT <format> |
|---|---|
| 导入示例 | clickhouse-client --query "INSERT INTO t FORMAT JSONEachRow" < data.jsonl |
| 批量建议 | 单次尽量千行级以上、控制每秒插入次数,避免大量小 part |
| 相关设置 | max_insert_block_size(默认约 104 万行)、insert_deduplicate(原子表默认去重) |
| 常见格式 | Values / JSONEachRow / CSV / TSV / Parquet |
| 写入单位 | 每次 INSERT 生成一个 part |
典型使用场景
- 小批量手工插入验证表结构与字段顺序
- 从文件批量导入外部数据(JSONEachRow / TSV / CSV)
- 表内加工复制:INSERT INTO … SELECT 做字段换算与过滤
- 实时链路攒批写入,先缓冲再批量落库
- 历史数据重放,注意幂等去重会造成重复块被丢弃
- 跨实例搬迁:导出为 Parquet 后在目标集群导入
示例
示例
INSERT INTO metrics (ts, metric, value) VALUES
(now(), 'cpu', 0.5),
(now(), 'mem', 0.7);
INSERT INTO metrics SELECT ts, metric, value * 2 FROM metrics WHERE metric = 'cpu';
-- 从 TSV 文件导入
-- clickhouse-client --query "INSERT INTO metrics FORMAT TSV" < metrics.tsv
-- 逐行 JSON 导入(每行一个对象)
-- clickhouse-client --query "INSERT INTO metrics FORMAT JSONEachRow" < data.jsonl写入方式对照
| 方式 | 适用场景 | 注意点 |
|---|---|---|
| VALUES | 小批量或调试 | 行数多时解析开销大 |
| SELECT | 表间加工与复制 | 源表过滤能省 IO |
| FORMAT + 文件 | 外部数据导入 | 字段顺序要与表定义一致 |
| HTTP 接口 | 程序化写入 | 适合按批 POST 数据体 |
同批次重复执行(相同 part 内容)时,Atomic 数据库下的表默认会做幂等去重,重试导入前先理解这个行为。
逐行 INSERT 是常见性能杀手:每条都产生一个 part,后台合并线程会被大量小 part 压垮,写入务必攒批。
Nullable 列导入空字符串与 NULL 语义不同,外部文件里的空值要提前和业务约定清楚,否则统计口径会偏离。
导入排错要点
- 报列数不匹配时先核对表定义与文件列顺序是否一致
- 导入慢先看 part 数量与合并线程状态,而不是盲目调大批次
- 大文件建议切成可重试的小批,失败只需重放当前批
- 导入前先核对目标表引擎与排序键,写错表结构后续查询无法裁剪
- 导入完成后用 count() 与源文件行数比对,差值优先怀疑格式解析失败