本踩坑指南视本人使用情况和本人心情不定期更新,很多是独家解决方案。如有更优解,欢迎在底下留言指出,共同探讨!

1. divide的分母为0判断无效

select divide(12.3456, 0);

返回是正常的,但是如果是正常数据库里面的内容

select divide(cost_sum, new_100_num)

在数据库字段中new_100_num的值为0时,会报错: DB::Exception: Division by zero: while executing 'FUNCTION divide 只能通过if子句来解决:

select
    if(cost_sum=0 or new_100_num = 0, cast(0 as Decimal(18,4)), cost_sum) / if(new_100_num = 0, 1, new_100_num) as cost_sum_new_100_num

2. round对于字段计算无效

select round(12.3456, 2)

结果是12.35是正常的,但是同样,在正常数据库的字段里面

select round(cost_sum/new_100_num, 2)
from stat.reports where cost_sum > 0 and new_100_num > 0;

结果却包括了4位小数点,原因是由于cost_sum是Decimal(18,4),解决方案是使用cast:

select cast(round(cost_sum/new_100_num, 2) as Decimal(18,2))
from stat.reports where cost_sum > 0 and new_100_num > 0;

3. if子句类型要一致

如果你的cost_sum是Decimal(18,4),则以下语句会报错:

select cast(if(cost_sum=0 or new_100_num = 0, 0, cost_sum) / if(new_100_num = 0, 1000000000, new_100_num) as Decimal(18,2)) as cost_sum_new_100_num

DB::Exception: Incompatible types of arguments corresponding to two conditional branches: while executing 是由于手动赋值的0这个数字是整型,而cost_sum是Decimal(18,4),需要做一层转化:

cast(if(cost_sum=0 or new_100_num = 0, cast(0 as Decimal(18,4)), cost_sum) / if(new_100_num = 0, 1000000000, new_100_num) as Decimal(18,2)) as cost_sum_new_100_num

4. json结果类型不匹配

对于UInt64字段类型,在指定FORMAT JSON后返回的json数据对于字段值会变成字符串,对于数据类型敏感的语言和业务场景,需要修改如下配置,在user.xml的中加入:

<output_format_json_quote_64bit_integers>0</output_format_json_quote_64bit_integers>

5. 一直存在的mutation

ch中所有ALTER UPDATE/DELETE操作,会写入system.mutations表。所有ch的mutation操作都是异步执行的。我们可以通过is_done=0来查看有哪些mutation是没有执行完成的。某些情况可能会导致mutation卡住,例如语法错误,这个时候可以手动清除mutation

KILL MUTATION WHERE database = '${db_name}' AND table = '${tbl_name}'

6.配置时区

默认时区为莫斯科,修改配置调整

vim /etc/clickhouse-server/config.xml
<timezone>Asia/Shanghai</timezone>

7.适当增加并发数

由于ch本身高并发性能有限,所以根据业务情况和机器配置可适当调整并发数,默认配置是100:

<max_concurrent_queries>100</max_concurrent_queries>

8.phpstorm和datagrip等客户端时间错乱

由于客户端配置问题,可能存在查询出来的时间和实际数据记录时间不匹配

配置->Advanced
1. use_server_time_zone 设置为=>   false
2. use_time_zone    设置为=>   Asia\Shanghai

注意,时区的斜杠是反的“\”

如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: clickhouse踩坑指南 - hisune.com