单表优化

PreWhere代替Where

PreWhere和Where的效果/语法都是一致的,都是用来过滤数据

但是PreWhere仅仅支持表引擎为*MergeTree

PreWhere的性能是Where的数十倍之多,CLK内部默认开启了优化操作,就算写的是Where,底层也会优化成PreWhere,不过官方还是建议尽量多的使用PreWhere

需要主要注意的是,PreWhere也会有失效的情况

如下图所示:

clickhouse查询语句java clickhouse where_大数据

分区查询和字段裁剪

没什么好说的,基本所有组件都是这种情况,尽量避免select*这种写法,最好是从分区中查询并且在此基础上查询出你想要的列,字段越少,消耗的IO资源越少,性能也就越高

order by + limit

尽量多的使用order和limit组合查询,尤其是数据量很大的情况下

避免虚拟列的产生

虚拟列指的就是表中没有的字段,比如
select a,b,a+b from test
a+b就是一个虚拟列,如果业务无法避开这种情况,建议在数仓的上一层进行计算,多落几个字段出来

uniqCombined 替代 distinct

Count(distinct xxx )这种写法在任何计算框架中都是毁灭性的打击
如果业务可以接受**2%**左右的误差值,可以使用uniqCombined(xxx)这种方式来代替Count(distinct xxx )的计算方式.虽然笔者并不这样建议

其他补充

设置单个SQL的查询时常,避免个别查询引起的服务雪崩
配置join_use_nulls,该配置可以在表与表关联的时候避免null值,从而使用默认值填充的效果

多表优化

CLK的JOIN(不论是哪种JOIN)是将右表的数据给放到内存中,然后逐条去匹配,所以CLK的官方建议是尽量减少JOIN操作
如果业务不可避免的做JOIN操作,在多表JOIN的时候要满足小表在右的原则
分布式情况下可以使用GLOBAL关键字进行开销损耗的减少
增加逻辑提前过滤/将常用的表作为字典表常驻于内存之中