Clickhouse分布式查询和写入优化


# clickhouse 查询优化

分布式子查询

1.普通的IN/JOIN:查询发送到远程的server,在每个远程的server上运行IN子查询或JOIN子句。
2.GLOBALIN/GLOBALJOIN:首先为GLOBALIN/GLOBALJOIN运行所有子查询,将结果收集在临时表中。然后将临时表发送到每个远端server,并在其中使用此临时数据运行查询。


普通操作 in 
SELECT uniq(UserID) FROM distributed_table WHERE UserID IN ( SELECT UserID FROM distributed_table_in WHERE CounterID=34 )

GLOBAL

SELECT uniq(UserID) FROM  distributed_table WHERE UserID GLOBAL IN (	SELECT	UserID FROM	distributed_table_in	WHERE	CounterID =34)

使用GLOBALIN/GLOBALJOIN注意事项
1.使用GLOBALIN创建临时表,数据没有去重。若要减少网络传输的数据量,在子查询中指定DISTINCT。
2.使用GLOBAL时,应尽量避免使用大数据集。临时表将发送到所有远程的主机,特别是在多机房容灾的集群架构下,数据发送至远程数据中心性能低下。
3.GLOBAL可能会导致网络超载。不会限制网络带宽。
4.使用GLOBAL时,尽量保证副本组驻留在同一个数据中心,保证快速的网络数据传输。
5.为避免GLOBAL导致的数据传输,可提前将全量的数据分发至每个节点,并使用普通JOIN/IN。

外部聚合/排序优化 max_bytes_before_external_group_by

  1. 聚合查询消耗的内存超过max_memory_usage(默认10G)设置的值,导致内存溢出。ClickHouse支持将临时数据转储到磁盘以限制GROUPBY期间的内存使用。当GROUPBY消耗超过max_bytes_before_external_group_by设置的阈值,ClickHouse将中间数据转储到磁盘。默认值为0,表示禁用磁盘溢写

  2. 聚合有两个阶段,第一阶段读取数据并形成中间数据。第二阶段合并中间数据。

中间临时数据转储到磁盘是发生在第一阶段,如果没有数据转储,则第两个阶段使用的内存相同。

  1. 参数建议 在设置max_bytes_before_external_group_by值时,建议将其设置为max_memory_usage的一半。当使用分布式查询,为了保证外部聚合时在远程的server端执行,设置distributed_aggregation_memory_efficient为1。
    备注:
 开启外部排序设置max_bytes_before_external_sort,否则可能会内存不足导致查询异常终止当启用外部聚合,
 如果数据没有转储到磁盘,此时,查询的运行速度和没有外部聚合时一样快。如果中间数据转储到磁盘,
 则运行时间将延长数倍(大约3倍)。而外部排序,数据转储到磁盘,性能将明显下降。
 三个参数分别设置为20G、10G和40G。1.在命令行界面设置:
setmax_bytes_before_external_group_by=20000000000;
setmax_bytes_before_external_sort=10000000000;
setmax_memory_usage=40000000000;
  1. JDBC设置,在URL添加参数:url?max_bytes_before_external_group_by=20000000000&max_memory_usage=40000000000

查询优化常用经验法则

  1. 小表放在JOIN的右边
  2. 使用子查询显式设置数据处理的顺序
  3. 使用IN替换JOIN操作
  4. 使用字典替换JOIN操作
  5. 设置单射属性6.使用Join引擎缓存表。
  6. 禁用分布式表的子查询,使用GLOBALIN/JOIN替换或者将子查询的表提前分发至所有的server作为本地表。
  7. 使用PREWHERE,谓词下推
  8. 避免使用SELECT*查询
  9. .尽量少用或不用多表关联。

选择和主键不一样的排序键

默认情况下,主键(由PRIMARYKEY指定)跟排序键(ORDERBY)相同,因此,大部分情况下,不需要专门指定一个PRIMARYKEY子句。当使用SummingMergeTree和AggregatingMergeTree时,可考虑选择和主键不一样的排序键。
1.排序键可以修改,主键不能修改。
2.预聚合/增量聚合的key是由排序键指定的。业务逻辑后期可能会更改。
3.查询条件无需包括排序键的所有字段。

注意

1. 主键字段是排序键字段的子集。例如主键为(A,B),则排序键以(A,B)开头,排序键可为(A,B)或(A,B,C)等。

2. 旧的排序键是新排序键的前缀。修改排序键只能增加排序字段,不能减少排序键字段,例如可修改排序键(A,B)为(A,B,C),但不能修改为(A,C)或(A,C,B)等。

3. 排序键只能添加新加入表的列,表中已存在数据的列不能添加到排序健中。

数据入库优化

  1. 使用复制表,能保证数据原子写入和去重。
  2. 限制单个复制表INSERT语句执行的频率(建议每秒不超过1个)
  3. 以相当大的数据块插入数据(默认为1048576)。
  4. 将数据INSERT到ClickHouse之前,通过分区键对数据进行分组。
  5. 增加入库的并发,入库性能线性提升。
    6 .自定义负载均衡策略,控制数据均衡

你可能感兴趣的:(clickhouse)