ClickHouse性能优化 1

简介: ClickHouse性能优化

1 Explain查看执行计划优化sql

在 clickhouse 20.6 版本之前要查看 SQL 语句的执行计划需要设置日志级别为 trace 才能可以看到,并且只能真正执行 sql,在执行日志里面查看。在 20.6 版本引入了原生的执行计划的语法。在 20.6.3 版本成为正式版本的功能。

本文档基于目前较新稳定版 21.7.3.14。

目前官网最新的在线测试链接:https://play.clickhouse.com/play?user=play

1.1 基本语法

EXPLAIN [AST | SYNTAX | PLAN | PIPELINE] [setting = value, ...] SELECT ... [FORMAT ...]

PLAN:用于查看执行计划,默认值。

header 打印计划中各个步骤的 head 说明,默认关闭,默认值 0;

description 打印计划中各个步骤的描述,默认开启,默认值 1;

actions 打印计划中各个步骤的详细信息,默认关闭,默认值 0。

AST :用于查看语法树;

SYNTAX:用于优化语法;

PIPELINE:用于查看 PIPELINE 计划。

header 打印计划中各个步骤的 head 说明,默认关闭;

graph 用 DOT 图形语言描述管道图,默认关闭,需要查看相关的图形需要配合graphviz 查看;

actions 如果开启了 graph,紧凑打印打,默认开启。

注:PLAN 和 PIPELINE 还可以进行额外的显示设置,如上参数所示。

1.2 案例实操

1.2.1 查看 PLAIN

  1. 简单查询
explain plan select arrayJoin([1,2,3,null,null]);
  1. 复杂 SQL 的执行计划
   explain select database,table,count(1) cnt from system.parts where database in ('datasets','system') group by database,table order by database,cnt desc limit 2 by database;

  1. 打开全部的参数的执行计划
   EXPLAIN header=1, actions=1,description=1 SELECT number from system.numbers limit 10;

1.2.2 AST 语法树

EXPLAIN AST SELECT number from system.numbers limit 10;

1.2.3 SYNTAX 语法优化

  1. 先做一次查询
   SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 'oldlu') FROM system.numbers limit 10;
  1. 查看语法优化
   EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 'oldlu') FROM  system.numbers limit 10;
  1. 开启三元运算符优化
SET optimize_if_chain_to_multiif = 1;
  1. 再次查看语法优化
   EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' :  'oldlu') FROM numbers(10);
  1. 返回优化后的语句
SELECT multiIf(number = 1, \\'hello\\', number = 2, \\'world\\', \\'xyz\\')
   FROM numbers(10)

1.2.4 查看 PIPELINE

EXPLAIN PIPELINE SELECT sum(number) FROM system.numbers_mt GROUP BY number % 20;

ade8cd005f6c4bdb8e80b81162f6ec40.png

//打开其他参数
EXPLAIN PIPELINE header=1,graph=1 SELECT sum(number) FROM system.numbers_mt GROUP BY number%20;

2 ClickHouse建表优化

2.1 数据类型

2.1.1 时间字段的类型

建表时能用数值型或日期时间型表示的字段就不要用字符串,全 String 类型在以 Hive为中心的数仓建设中常见,但 ClickHouse 环境不应受此影响。

虽然 ClickHouse 底层将 DateTime 存储为时间戳 Long 类型,但不建议存储 Long 类型,因为 DateTime 不需要经过函数转换处理,执行效率高、可读性好。

create table t_type2(
id UInt32,
sku_id String,
total_amount Decimal(16,2) ,
create_time Int32 
) engine =ReplacingMergeTree(create_time)
partition by toYYYYMMDD(toDate(create_time)) –-需要转换一次,否则报错
primary key (id)
order by (id, sku_id);

2.1.2 空值存储类型

官方已经指出 Nullable 类型几乎总是会拖累性能,因为存储 Nullable 列时需要创建一个额外的文件来存储 NULL 的标记,并且 Nullable 列无法被索引。因此除非极特殊情况,应直接使用字段默认值表示空,或者自行指定一个在业务中无意义的值(例如用-1 表示没有商品ID)。

CREATE TABLE t_null(x Int8, y Nullable(Int8)) ENGINE TinyLog;
INSERT INTO t_null VALUES (1, NULL), (2, 3);
SELECT x + y FROM t_null;

查看存储的文件:(没有权限就用 root 用户)

官网说明:https://clickhouse.com/docs/zh/sql-reference/data-types/nullable/

2.2 分区和索引

分区粒度根据业务特点决定,不宜过粗或过细。一般选择按天分区,也可以指定为 Tuple(),以单表一亿数据为例,分区大小控制在 10-30 个为最佳。

 必须指定索引列,ClickHouse 中的索引列即排序列,通过 order by 指定,一般在查询条件中经常被用来充当筛选条件的属性被纳入进来,且查询越频繁的字段越要靠前;可以是单一维度,也可以是组合维度的索引;通常需要满足高级列在前、查询频率大的在前原则;还有基数特别大的不适合做索引列,如用户表的 userid 字段;通常筛选后的数据满足在百万以内为最佳。

 比如官方案例的 hits_v1 表:

……
PARTITION BY toYYYYMM(EventDate)
ORDER BY (CounterID, EventDate, intHash32(UserID))
……

visits_v1 表:

……
PARTITION BY toYYYYMM(StartDate)
ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID)
……
1234

2.3 表参数

Index_granularity 是用来控制索引粒度的,默认是 8192,如非必须不建议调整。

 如果表中不是必须保留全量历史数据,建议指定 TTL(生存时间值),可以免去手动过期历史数据的麻烦,TTL 也可以通过 alter table 语句随时修改。(参考基础文档 4.4.5 数据 TTL)

2.4 写入和删除优化

(1)尽量不要执行单条或小批量删除和插入操作,这样会产生小分区文件,给后台Merge 任务带来巨大压力

 (2)不要一次写入太多分区,或数据写入太快,数据写入太快会导致 Merge 速度跟不上而报错,一般建议每秒钟发起 2-3 次写入操作,每次操作写入 2w~5w 条数据(依服务器性能而定)

 写入过快报错,报错信息:

1. Code: 252, e.displayText() = DB::Exception: Too many parts(304). Merges are processing significantly slower than inserts
2. Code: 241, e.displayText() = DB::Exception: Memory limit (for query) exceeded:would use 9.37 GiB (attempt to allocate chunk of 301989888 bytes), maximum: 9.31 GiB

处理方式:

Too many parts 处理使用 WAL 预写日志,提高写入性能

  in_memory_parts_enable_wal 默认为 true


在服务器内存充裕的情况下增加内存配额,一般通过 max_memory_usage 来实现

 在服务器内存不充裕的情况下,建议将超出部分内容分配到系统硬盘上,但会降低执行速度,一般通过 max_bytes_before_external_group_by、max_bytes_before_external_sort 参数来实现。

目录
相关文章
|
SQL 存储 算法
ClickHouse性能优化 3
ClickHouse性能优化
1059 0
|
存储 SQL 关系型数据库
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
ClickHouse的核心架构包括执行过程和数据存储两部分。执行过程涉及Parser与Interpreter解析SQL,通过Column、DataType、Block、Functions和Storage模块处理数据。Column是内存中列的表示,Field处理单个值,DataType负责序列化和反序列化,Block是内存中表的子集,Block Streams处理数据流。Storage代表表,使用不同的引擎如StorageMergeTree。数据存储基于分片和副本,1个分片由多个副本组成,每个节点只能拥有1个分片。
1226 0
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
|
OLAP 数据库 索引
59.【clickhouse】ClickHouse从入门到放弃-分区表
【clickhouse】ClickHouse从入门到放弃-分区表
59.【clickhouse】ClickHouse从入门到放弃-分区表
|
12月前
|
存储 SQL 自然语言处理
ClickHouse查询执行与优化
本文详细介绍了SQL语法扩展、执行计划分析及优化策略,涵盖特殊函数与子句(如`WITH`、`ANY JOIN`)、聚合函数扩展(如`uniqCombined`、`quantileTDigest`)以及执行计划优化技巧。同时深入解析了ClickHouse的索引原理,包括主键索引和跳数索引的工作机制与优化方法。针对查询优化,文章提供了过滤条件下推、分布式查询优化和数据预聚合等策略,并探讨了资源管理与并发控制的核心参数(如`max_memory_usage`、`max_threads`)及队列优先级调度机制,助力高效使用ClickHouse。
1494 9
|
8月前
|
存储 数据挖掘 Apache
浩瀚深度:从 ClickHouse 到 Doris, 支撑单表 13PB、534 万亿行的超大规模数据分析场景
浩瀚深度旗下企业级大数据平台选择 Apache Doris 作为核心数据库解决方案,目前已在全国范围内十余个生产环境中稳步运行,其中最大规模集群部署于 117 个高性能服务器节点,单表原始数据量超 13PB,行数突破 534 万亿,日均导入数据约 145TB,节假日峰值达 158TB,是目前已知国内最大单表。
1530 10
浩瀚深度:从 ClickHouse 到 Doris, 支撑单表 13PB、534 万亿行的超大规模数据分析场景
|
存储 SQL 缓存
优化ClickHouse查询性能:最佳实践与调优技巧
【10月更文挑战第26天】在大数据分析领域,ClickHouse 以其卓越的查询性能和高效的列式存储机制受到了广泛的关注。作为一名已经有一定 ClickHouse 使用经验的开发者,我深知在实际应用中,合理的表设计、索引优化以及查询优化对于提升 ClickHouse 性能的重要性。本文将结合我的实践经验,分享一些有效的优化策略。
1911 3
|
负载均衡 数据管理
ClickHouse的分布式查询流程
ClickHouse的分布式查询流程
|
SQL 分布式计算 关系型数据库
Clickhouse时间日期函数一文详解+代码展示
Clickhouse时间日期函数一文详解+代码展示
4673 0
Clickhouse时间日期函数一文详解+代码展示
|
存储 SQL 关系型数据库
ClickHouse(09)ClickHouse合并树MergeTree家族表引擎之MergeTree详细解析
ClickHouse的MergeTree系列引擎是其高性能大数据存储的核心,特别适合大量数据的快速插入。数据按主键排序,支持分区和数据副本,提供数据采样功能。建表时,通过`ENGINE = MergeTree()`指定引擎,`ORDER BY`指定排序键,可选`PARTITION BY`分区,`SAMPLE BY`进行采样。此外,MergeTree支持多种索引和设置,如`index_granularity`控制索引粒度。查询时,ClickHouse利用主键和索引来高效检索数据,尤其在使用等值或范围条件时。
739 0
|
数据采集 存储 分布式计算
ClickHouse大规模数据导入优化:批处理与并行处理
【10月更文挑战第27天】在数据驱动的时代,高效的数据导入和处理能力是企业竞争力的重要组成部分。作为一位数据工程师,我在实际工作中经常遇到需要将大量数据导入ClickHouse的需求。ClickHouse是一款高性能的列式数据库系统,非常适合进行大规模数据的分析和查询。然而,如何优化ClickHouse的数据导入过程,提高导入的效率和速度,是我们面临的一个重要挑战。本文将从我个人的角度出发,详细介绍如何通过批处理、并行处理和数据预处理等技术优化ClickHouse的数据导入过程。
1690 0