本文共 2201 字,大约阅读时间需要 7 分钟。
虽然ClickHouse底层将DateTime存储为时间戳Long类型,但不建议直接使用Long类型存储DateTime字段。这种做法虽然高效,但可能会影响数据的可读性。建议直接使用DateTime类型,这样无需经过函数转换处理,能够提升执行效率。
在处理Nullable类型时,需要特别注意性能问题。Nullable列需要创建额外的文件来存储NULL标记,这不仅会影响查询性能,还会导致索引无法建立。因此,除非有特殊需求,否则建议通过设置字段默认值或在业务中自定义无意义的值(如-1)来表示空值,而不是直接使用Nullable类型。
分区的粒度需要根据业务特点来决定,不能过于粗或过于细。一般推荐按天分区,也可以使用tuple()的方式。以单表存储1亿数据为例,分区大小控制在10-30个为最佳。
在索引方面,必须指定索引列。ClickHouse中的索引列即排序列,通常通过order by命令指定。索引列可以是单一维度,也可以是多维度的组合。建议遵循高基列在前、查询频率大的在前的原则。此外,基数特别大的字段(如用户表的userid字段)不适合作为索引列。一般情况下,查询结果返回的数据量越少(如百万以内),查询性能会更好。
index_granularity是用来控制索引粒度的参数,默认值为8192。除非有特殊需求,否则不建议调整这个参数。
如果表中不需要保留全量历史数据,可以通过设置TTL(时间到期)来自动过期历史数据,这样可以减少手动清理的工作量。此外,TTL也可以随时通过ALTER TABLE语句修改。
在进行单表查询时,建议使用prewhere替代where关键字。当查询的字段数量明显多于筛选条件时,使用prewhere可以将查询性能提升10倍左右。
例如:
SELECT * FROM fl_db.stock_plate sp prewhere code='600570';
数据采样是提升数据分析性能的重要手段。通过合理采样,可以显著减少数据处理的开销。对于数据量过大的情况,建议避免使用SELECT *操作,因为这会与查询的字段数量和字段大小成线性关系,影响性能。字段越少,IO资源消耗越少,查询速度会更快。
在进行order by查询时,数据量超过千万时,建议结合where条件和limit语句一起使用,以确保查询性能。
对于虚拟列,建议尽量避免在结果集中构建,特别是在数据量较大时。虚拟列会消耗大量资源,影响性能。可以通过前端处理或在表中实际存储字段来解决问题。
在进行去重操作时,建议避免使用distinct去重,而是使用uniqCombined来进行近似去重。对于大数据量的去重操作,这种方法会更高效。
在进行多表Join操作时,必须遵循小表在右的原则。右表关联时会被加载到内存中,与左表进行比较,这样可以减少磁盘IO操作的开销。
ClickHouse不支持设置多数据目录。为了提升数据IO性能,可以通过挂载虚拟卷组的方式,将多块物理磁盘绑定在一起。这样可以显著提升读写性能。对于大多数查询场景,使用SSD盘会比普通机械硬盘快2-3倍。
1. JOIN操作时,右表必须是小表。ClickHouse中无论是Left Join、Right Join还是Inner Join都会将右表的每条记录与左表匹配查找,因此右表必须是小数据表。
2. 为每个账户添加join_use_nulls配置。ClickHouse的SQL语法与标准SQL有所不同,默认情况下,如果左表中存在记录在右表中不存在的情况,右表的相应字段会返回默认值,而不是标准SQL中的Null值。这对于习惯了标准SQL的开发人员来说可能会带来困扰。
3. 在使用ClickHouse的JDBC驱动进行批量写入数据时,必须控制每个批次涉及的分区数量。在写入数据之前,建议通过Order By语句对需要导入的数据进行排序。无序数据或涉及大量分区的数据可能会导致ClickHouse无法及时合并新导入的数据,从而影响查询性能。
4. 尽量减少JOIN操作时左右表的数据量。当需要进行JOIN时,可以考虑对某个表进行聚合操作,减少数据条数。有些情况下,先GROUP BY再JOIN可能比先JOIN再GROUP BY查询时间更短。
5. ClickHouse的版本迭代较快,建议使用去年的稳定版本。新版本可能会有语法不兼容或其他问题,虽然没有报错,但可能会导致内存泄漏等问题。
6. 避免使用分布式表。ClickHouse的分布式表性能上性价比不如单独的物理表,特别是当分区字段值过多时,数据导入过程可能会导致磁盘被打满。
7. 关注服务器的CPU使用率。一般情况下,CPU使用率在50%左右为正常。当CPU达到70%时,查询可能会出现大范围的超时。因此,我们通常对所有ClickHouse查询都进行监控,当出现波动时会发送预警邮件。
8. 查询测试Case的数据量为:6000万数据关联1000万数据再关联2000万数据,sum一个月的夜间数据,返回结果为190ms;2.4亿数据关联2000万数据group by一个月的数据大概需要390ms。ClickHouse的查询性能与查询条件密切相关,同一张表在不同的查询条件下可能需要不同的优化策略。
转载地址:http://vffcz.baihongyu.com/