有奖捉虫:行业应用 & 管理与支持文档专题 HOT
文档中心 > 最佳实践 > 腾讯云数据仓库 TCHouse-C > ClickHouse 内核使用建议与规范
使用 ClickHouse 时需注意以下规范:

写入规范

1. 攒批写入:ClickHouse 必须攒批写入,至少 1000 条/批,建议 5k - 10w 一批写入ClickHouse,每一次写入都会在底层生成 1 个或者多个 part 存储目录,后台任务自动合并小 part 到一个大 part ,如果写入频次过高会出现 part 过多,merge 速度跟不上导致写入失败报错: Too many parts(301). Merges are processing significantly slower than inserts
2. 减少分布式表直接写入:为了提高写入和查询性能,应尽可能直接写入本地表,而不是分布式表。写分布式表最终也会转发给本地表,但是分布式表存在写放大以及异步落盘消耗 IO 的问题,写入性能较差。
3. 约束数据一致性:ClickHouse 不支持数据写入的事务保证,因此需要通过外部导入数据模块来控制数据的幂等性。例如,如果某个批次的数据导入异常,可以删除对应的分区数据或清理导入的数据,然后重新导入该分区或批次的数据。也可以使用去重引擎(replacingMergetree)来保证最终一致性。
4. 大规模数据写入:如果需要进行大规模数据写入,建议提前拆分数据,并按节点均匀地写入 ClickHouse 的各个节点。如果存在特定的分布规则,可以在业务侧进行 hash 计算。
5. 一次只写入一个分区数据:为了避免写入性能下降和目录数量过多的问题,应该一次只写入一个分区的数据。如果一批写入数据跨多个分区,会导致底层产生多个 part 文件,消耗更多的 merge 性能,并且不利于幂等控制。

查询规范

单表查询

1. 高频过滤和点查询字段使用索引加速。
2. 避免使用select * 语句,应该明确需要查询的字段,只查询必要的字段。ClickHouse 底层是列式存储,查询的耗时与查询的字段大小和数量成线性关系。
3. 当查询千万以上的数据集时,建议使用where条件和limit语句来配合order by查询,以提高查询效率。
4. select {tablename} final 能够实现查询 ( read on merge ),但是会减慢查询速度,需要有针对性使用。
5. 尽量按分区过滤裁剪,通过指定分区字段可以减少底层数据库扫描的文件数量,提高查询性能。
6. 谨慎使用 delete 和 update 的 mutation 操作。ClickHouse 的 update 和 delete 是异步进行的,并且会重写 where 条件过滤出的数据 part ,是非常重的操作,可能会消耗较多系统资源。此外,update 和 delete 是按照 part 逐个执行,不会保证整体执行的原子性。
7. 如果对唯一性要求不高,可以采用近似去重 uniqCombined 来优化去重逻辑,从而提高十倍的查询性能。如果查询允许有误差,可以使用 uniqCombined 替代,否则应该继续使用 distinct 语法。使用 distinct 会对查询性能有一定影响。

多表关联

1. 为了避免 Join 操作和 shuffle ,应尽量使用 Flat 大宽表结构代替多表 Join 。
2. 控制 Join 的表数量,尽量保持在3个及以下。
3. 如果查询字段出自单表,可考虑将 Join 改为 in 查询 ,CK 中的 in 查询支持单字段和 tuple ,例如 SELECT name FROM tab_a WHERE id IN (SELECT id FROM tab_b WHERE name = ‘xx’)。
4. 多表 Join 最好改为两表 Join 和子查询形式。
5. 两表 Join 需大表 Join 小表(数据量控制在百万 - 千万行级别),小表 Join 小表,不允许大表 Join 大表;Join 时大表需在左边,小表在右边。
6. 建议使用列裁剪、分区裁剪,Join 前进行条件过滤,尽可能降低 Join 数据量。
7. 若 Join 时右表为子查询或者分布式表且数据不大,可以采用 GLOBAL JOIN 避免读放大,需要注意的是,GLOBAL JOIN 会触发数据在节点之间传播,占用部分网络流量。如果数据量较大,同样会带来性能损失。

建表规范

1. 高可用集群不可创建非 Replicated 表,非高可用集群不可创建 Replicated 表。
2. 如果对数据最终一致性有强要求,需要使用 ReplacingMergeTree 或者 CollapsingMergeTree 引擎,并定期进行 optimize 或使用 select {tablename} final 实现最终去重。
3. 在规划分区时,应该合理规划分区个数,并尽可能利用分区。一张表分区数不建议超过 1000 个,可以在查询时有效帮助进行数据过滤,使用得当可以提升数倍查询性能,通常按天分区是比较普遍的做法。分区也不建议过多,因为 ClickHouse 不同分区的数据不会合并,容易导致 part 过多,从而导致查询和重启变得很慢。
4. 建表时尽可能提前规划好表字段,并尽量避免删改字段。删改字段会重写整个表的全量数据,对于大表会消耗大量资源,执行时间可能很长。此外,删改字段期间也容易阻塞其他 DDL 语句,影响表的 merge 操作。如果中途出错,有概率会导致不可预知的数据一致性问题。
5. 禁止修改索引列,对索引列的修改会导致现有索引失效,触发重建索引,期间查询数据不准确。
6. 约束 COS 上存储数据的量,尽可能避免对冷分区进行写入和 mutation 操作。COS 单个桶大约只有1GB的带宽,远低于多节点的本地盘和云盘性能,且网络延迟比较高。如果 COS 上存储过多数据,会严重影响查询效率。针对 COS 分区的写入时,会触发 COS 分区进行 merge ,merge 效率也会降低甚至会影响本地盘的数据操作。
?


http://www.vxiaotou.com