一 使用执行计划
ClickHouse官网执行计划详解 平常写sql的时候,有时候因为我们的有限的水平,写出的sql很差,ck为我们提供了执行计划查询的方法,通过此,我们可以优化我们的sql
#官网的执行计划查看
EXPLAIN [AST | SYNTAX | PLAN | PIPELINE] [setting = value, ...] SELECT ... [FORMAT ...]
以简单的sql
select groupArray(item_id) from user prewhere toYear(times)=2017 group by times;
一 查看执行计划
添加执行计划查看
explain plan select groupArray(item_id) from user prewhere toYear(times)=2017 group by times;
查看执行的语法树逻辑
explain AST select groupArray(item_id) from user prewhere toYear(times)=2017 group by times;
三 使用explain SYNTAX 优化语句
下面是一条很脑的sql
select item_id in (select item_id from user ) from user where toYear(times)=2017;
在语句前添加一个 explain SYNTAX
explain SYNTAX select item_id in (select item_id from user ) from user where toYear(times)=2017;
执行可以得到clickhouse帮我们优化后的成果
select item_id in ((select item_id from user) as _subquery7)from user prewhere toYear(times)=2017;
执行优化后的语句,可以看出速度快了接近0.05s,这个效果已经很明显了,如果更复杂的语句,优化后语句效果更明显
二 不要用join
clickhouse的本身适用于单宽表,多表连接性能下降的很快,join可以用其他语句替代这些来代替,因为使用join的话,简直是灾难,即使是要join,也不要把大表放在右边。这是由于clickhouse的反人类设计,进行join时,clickhouse会将右表全部加载到内存里,再一条条匹配,速度就会迅速降低。
下面测试两个表的大小为(暂时不考虑逻辑)
select a.name,a.city,a.url,a.new_price,b.trade_place from hotel_name_rank a left join trade_city b on b.name=a.name;
select a.name,a.city,a.url,a.new_price,b.trade_place from hotel_name_rank a right join trade_city b on b.name=a.name;
使用where
select a.name,a.city,a.url,a.new_price,b.trade_place from hotel_name_rank a, trade_city b where b.name=a.name;
这是我从尚硅谷课程的截图
三 使用prewhere替代where
PREWHERE能有效支持过滤,默认是开启的,但仅由系列中的表支持*MergeTree系列引擎
四 不使用nullable
nullable无法被索引,因此需要,还需要建立特定的文件来标记,因此平常使用建议使用一些标记值替代nullable
五 近似去重
一些实时的领域,如需要去重,distinct太耗时,可以使用uniq