文章目录
- 一、简介
- 1、OLAP 与 OLTP 的对比
- 2、列式储存的好处
- 3、DBMS 的功能
- 4、多样化引擎
- 5、高吞吐写入能力
- 6、数据分区与线程级并行
- 二、Explain 查看执行计划
- 三、建表优化
- 1、数据类型
- 2、分区和索引
- 3、表参数
- 4、写入和删除优化
- 四、常见配置
- CPU资源
- 内存资源
- 存储
- 五、ClickHouse 语法优化规则
- 1、COUNT 优化
- 2、消除子查询重复字段
- 3、谓词下推
- 4、聚合计算外推
- 5、聚合函数消除
- 6、删除重复的Key
- 7、标量替换
- 8、三元运算优化
- 六、查询优化
- 1、单表查询
- 数据采样
- 列裁剪与分区裁剪
- orderby 结合 where、imit
- 避免构建虚拟列
- uniqCombined 替代 distinct
- 使用物化视图
- 其他注意事项
- 2、多表关联
- 用 IN 代替 JOIN
- 大小表 JOIN
- 注意谓词下推(版本差异)
- 分布式表使用 GLOBAL
- 使用字典表
- 提前过滤
- 七、数据一致性(重点)
- 八、物化视图
- 1、概念
- 2、物化视图与普通视图的区别
- 3、优点
- 4、缺点
- 九、MaterializeMySQL 引擎
- 十、常见问题排查
- 1、分布式 DDL 某数据节点的副本不执行
- 2、数据副本表和数据不一致
- 3、副本节点全量恢复
- 4、数据副本启动缺少 zk 表
- 5、ZK table replicas 数据未删除,导致重建表报错
- 6、Clickhouse 节点意外关闭
- 7、其他问题参考
- 十一、监控以及数据备份
- 十二、总结
- 1. 特性优势
- 2. 操作使用
- 3. 语法与查询优化
- 3. 语法与查询优化
本篇ClickHouse版本21.7.3.14,面向快速全面了解ClickHouse
下面文档链接是最新的,可以查看官方文档了解最新信息
一、简介
什么是 ClickHouse? | ClickHouse Docs
ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库(DBMS),使用 C++语言编写,主要用于在线分析处理查询(OLAP),能够使用 SQL 查询实时生成分析数据报告。
1、OLAP 与 OLTP 的对比
对比项 | OLTP(例如:MySql) | OLAP |
---|---|---|
主要目的 | 处理日常事务 | 支持决策分析 |
数据特点 | 当前、最新数据 | 历史、综合数据 |
操作类型 | 增删改查 | 复杂查询、数据分析 |
用户群体 | 普通业务用户 | 企业管理层、分析师 |
系统设计 | 注重事务处理性能和并发控制 | 注重数据分析能力和查询性能优化 |
2、列式储存的好处
- 对于列的聚合,计数,求和等统计操作原因优于行式存储
- 节省了磁盘空间和提高了数据的压缩比重。
3、DBMS 的功能
几乎覆盖了标准 SQL 的大部分语法,包括 DDL 和 DML,以及配套的各种函数,用户管
理及权限管理,数据的备份与恢复。
4、多样化引擎
目前包括合并树、日志、接口和其他四大类 20 多种引擎。
5、高吞吐写入能力
ClickHouse 采用类 LSM Tree的结构,导入时全部是顺序 append 写,即便在 HDD 上也有着优异的写入性能。
官方公开 benchmark 测 试显示能够达到 50MB-200MB/s 的写入吞吐能力,按照每行100Byte 估算,大约相当于 50W-200W 条/s 的写入速度。
6、数据分区与线程级并行
单条 Query 就能利用整机所有 CPU
弊端:对于单条查询使用多 cpu,就不利于同时并发多条查询。
二、Explain 查看执行计划
EXPLAIN [explain_mode] SELECT query;
ClickHouse 支持以下几种 explain_mode
:
SYNTAX
:只解析查询语句的语法,不分析执行计划。这通常用于快速检查查询语句的语法是否正确。PIPELINE
:显示查询的执行计划,包括查询的各个阶段和操作符。这是最常用的模式。AST
:显示查询的抽象语法树(Abstract Syntax Tree),这对于理解查询的结构和解析过程很有帮助。
三、建表优化
1、数据类型
-
时间字段的类型
使用分区类型使用DateTime
partition by toYYYYMMDD(toDate(create_time)) –- 需要转换一次,否则报错
-
避免空值
空值存储类型 Nullable(T) | ClickHouse Docs
官方:Nullable 类型几乎总是会拖累性能
原因
- 多存一个文件
- 无法被索引
使用字段默认值表示空,或者自行指定一个在业务中无意义的值
2、分区和索引
- 分区粒度根据业务特点决定,不宜过粗或过细。一般选择按天分区,也可以指定为 Tuple(),以单表一亿数据为例,分区大小控制在 10-30 个为最佳。
- 必须指定索引列,ClickHouse 中的 索引列即排序列,通过 order by 指定,一般在查询条件中经常被用来充当筛选条件的属性被纳入进来;可以是单一维度,也可以是组合维度的索引;通常需要满足高级列在前、查询频率大的在前原则;还有基数特别大的不适合做索引列,如用户表的 userid 字段;通常筛选后的数据满足在百万以内为最佳。
3、表参数
- Index_granularity 是用来控制索引粒度的,默认是 8192,如非必须不建议调整。
- 如果表中不是必须保留全量历史数据,建议指定 TTL(生存时间值),可以免去手动过期历史数据的麻烦,TTL 也可以通过 alter table 语句随时修改。
4、写入和删除优化
- 尽量不要执行单条或小批量删除和插入操作,这样会产生小分区文件,给后台Merge 任务带来巨大压力
- 不要一次写入太多分区,或数据写入太快,数据写入太快会导致 Merge 速度跟不上而报错,一般建议每秒钟发起 2-3 次写入操作,每次操作写入 2w~5w 条数据(依服务器性能而定)
写入过快报错
处理方式:
- “ Too many parts 处理 ” :使用 WAL 预写日志,提高写入性能。in_memory_parts_enable_wal 默认为 true
- 在服务器内存充裕的情况下增加内存配额,一般通过 max_memory_usage 来实现
- 在服务器内存不充裕的情况下,建议将超出部分内容分配到系统硬盘上,但会降低执行速度,一般通过 max_bytes_before_external_group_by、max_bytes_before_external_sort 参数来实现。
四、常见配置
配置项主要在 config.xml 或 users.xml 中, 基本上都在 users.xml 里
Users and Roles Settings | ClickHouse Docs
Global Server Settings | ClickHouse Docs
CPU资源
配置 | 描述 |
---|---|
background_pool_size | 后台线程池的大小,merge 线程就是在该线程池中执行,该线程池不仅仅是给 merge 线程用的,默认值 16,允许的前提下建议改成 cpu 个数的 2 倍(线程数) |
background_schedule_pool_size | 执行后台任务(复制表、Kafka 流、DNS 缓存更新)的线程数。默认 128,建议改成 cpu 个数的 2 倍(线程数)。 |
background_distributed_schedule_pool_size | 设置为分布式发送执行后台任务的线程数,默认 16,建议改成 cpu个数的 2 倍(线程数)。 |
max_concurrent_queries | 最大并发处理的请求数(包含 select,insert 等),默认值 100,推荐 150(不够再加)~300 |
max_threads | 设置单个查询所能使用的最大 cpu 个数,默认是 cpu 核数 |
内存资源
配置 | 描述 |
---|---|
max_memory_usage | 此参数在 users.xml 中,表示单次 Query 占用内存最大值,该值可以设置的比较大,这样可以提升集群查询的上限。保留一点给 OS,比如 128G 内存的机器,设置为 100GB。 |
max_bytes_before_external_group_by | 一般按照 max_memory_usage 的一半设置内存,当 group 使用内存超过阈值后会刷新到磁盘进行。因为 clickhouse 聚合分两个阶段:查询并及建立中间数据、合并中间数据,结合上一项,建议 50GB。 |
max_bytes_before_external_sort | 当 order by 已使用 max_bytes_before_external_sort 内存就进行溢写磁盘(基于磁盘排序),如果不设置该值,那么当内存不够时直接抛错,设置了该值 order by 可以正常完成,但是速度相对存内存来说肯定要慢点(实测慢的非常多,无法接受)。 |
max_table_size_to_drop | 此参数在 config.xml 中,应用于需要删除表或分区的情况,默认是50GB,意思是如果删除 50GB 以上的分区表会失败。建议修改为 0,这样不管多大的分区表都可以删除 |
存储
ClickHouse 不支持设置多数据目录,为了提升数据 io 性能,可以挂载虚拟券组,一个券组绑定多块物理磁盘提升读写性能,多数据查询场景 SSD 会比普通机械硬盘快 2-3 倍。
五、ClickHouse 语法优化规则
1、COUNT 优化
在调用 count 函数时,如果使用的是 count() 或者 count(*),且没有 where 条件,则会直接使用 system.tables 的 total_rows
如果 count 具体的列字段,则不会使用此项优化
2、消除子查询重复字段
3、谓词下推
当 group by 有 having 子句,但是没有 with cube、with rollup 或者 with totals 修饰的时候,having 过滤会下推到 where 提前过滤。例如下面的查询,HAVING name 变成了 WHERE name,在 group by 之前过滤:
4、聚合计算外推
聚合函数内的计算,会外推
EXPLAIN SYNTAX
SELECT sum(UserID * 2)
FROM visits_v1
//返回优化后的语句
SELECT sum(UserID) * 2
FROM visits_v1
5、聚合函数消除
如果对聚合键,也就是 group by key 使用 min、max、any 聚合函数,则将函数消除
6、删除重复的Key
order by key
重复的聚合键字段会被去重limit by key
USING Key
7、标量替换
8、三元运算优化
六、查询优化
1、单表查询
Prewhere 替代 where
- Prewhere 和 where 语句的作用相同,用来过滤数据。不同之处在于 prewhere 只支持MergeTree 族系列引擎的表,首先会读取指定的列数据,来判断数据过滤,等待数据过滤之后再读取 select 声明的列字段来补全其余属性。
- 当查询列明显多于筛选列时使用 Prewhere 可十倍提升查询性能,Prewhere 会自动优化执行过滤阶段的数据读取方式,降低 io 操作。
- 在某些场合下,prewhere 语句比 where 语句处理的数据量更少性能更高。
默认情况,我们肯定不会关闭 where 自动优化成 prewhere,但是某些场景即使开启优化,也不会自动转换成 prewhere,需要手动指定prewhere
- 使用常量表达式
- 使用默认值为 alias 类型的字段
- 包含了 arrayJOIN,globalIn,globalNotIn 或者 indexHint 的查询
- select 查询的列字段和 where 的谓词相同
- 使用了主键字段
数据采样
通过采样运算可极大提升数据分析的性能
SELECT Title,count(*) AS PageViews
FROM hits_v1 SAMPLE 0.1 -- 代表采样 10%的数据,也可以是具体的条数
WHERE CounterID =57
GROUP BY Title
ORDER BY PageViews DESC LIMIT 1000
采样修饰符只有在 MergeTree engine 表中才有效,且在创建表时需要指定采样策略。
列裁剪与分区裁剪
数据量太大时应避免使用 select * 操作,查询的性能会与查询的字段大小和数量成线性表换,字段越少,消耗的 io 资源越少,性能就会越高。
orderby 结合 where、imit
千万以上数据集进行 order by 查询时需要搭配 where 条件和 limit 语句一起使用
避免构建虚拟列
如非必须,不要在结果集上构建虚拟列,虚拟列非常消耗资源浪费性能,可以考虑在前端进行处理,或者在表中构造实际字段进行额外存储。
-- 反例:
SELECT Income,Age,Income/Age as IncRate FROM datasets.hits_v1;
-- 正例:拿到 Income 和 Age 后,考虑在前端进行处理,或者在表中构造实际字段进行额外存储
SELECT Income,Age FROM datasets.hits_v1;
uniqCombined 替代 distinct
- 性能可提升 10 倍以上,uniqCombined 底层采用类似 HyperLogLog 算法实现,能接收 2%左右的数据误差,可直接使用这种去重方式提升查询性能。Count(distinct )会使用 uniqExact精确去重。
- 不建议在千万级不同数据上执行 distinct 去重查询,改为近似去重 uniqCombined
使用物化视图
- 物化视图基于一个或多个基表(或其他物化视图)创建,它实际上是将查询结果持久化存储在磁盘上。当基表数据发生变化时,物化视图可以自动更新,以反映最新的数据状态。
- 当基表数据发生插入、更新或删除操作时,ClickHouse 会自动将这些变化应用到相关的物化视图中。这是通过后台的
Mutation
操作实现的,它会在基表数据变化时触发,并根据物化视图的定义来更新相应的数据。例如,如果向orders
表中插入了一条新的订单记录,customer_order_count
物化视图会自动更新对应客户的订单总数。
使用场景
- 数据聚合:常用于预先计算和存储聚合数据,如统计报表、指标计算等场景。例如,计算每日、每月的销售总额、平均订单金额等。
- 数据预处理:可以对原始数据进行预处理,将其转换为更适合特定查询或分析的格式。例如,对文本数据进行分词、对时间序列数据进行采样等。
- 加速复杂查询:对于复杂的多表连接查询或包含大量计算的查询,可以将结果存储在物化视图中,以提高后续查询的速度。这样,在需要获取相同或类似数据时,无需再次执行复杂的查询逻辑,直接从物化视图中获取数据即可。
其他注意事项
-
查询熔断
为了避免因个别慢查询引起的服务雪崩的问题,除了可以为单个查询设置超时以外,还可以配置周期熔断,在一个查询周期内,如果用户频繁进行慢查询操作超出规定阈值后将无法继续进行查询操作。
-
关闭虚拟内存
物理内存和虚拟内存的数据交换,会导致查询变慢,资源允许的情况下关闭虚拟内存。
-
配置join_use_nulls
为每一个账户添加 join_use_nulls 配置,左表中的一条记录在右表中不存在,右表的相应字段会返回该字段相应数据类型的默认值,而不是标准 SQL 中的 Null 值。
-
批量写入时先排序
批量写入数据时,必须控制每个批次的数据中涉及到的分区的数量,在写入之前最好对需要导入的数据进行排序。无序的数据或者涉及的分区太多,会导致 ClickHouse 无法及时对新导入的数据进行合并,从而影响查询性能。
-
关注CPU
cpu 一般在 50%左右会出现查询波动,达到 70%会出现大范围的查询超时,cpu 是最关键的指标,要非常关注。
2、多表关联
用 IN 代替 JOIN
当多表联查时,查询的数据仅从其中一张表出时,可考虑用 IN 操作而不是 JOIN
大小表 JOIN
多表 join 时要满足小表在右的原则,右表关联时被加载到内存中与左表进行比较,ClickHouse 中无论是 Left join 、Right join 还是 Inner join 永远都是拿着右表中的每一条记录到左表中查找该记录是否存在,所以右表必须是小表。
注意谓词下推(版本差异)
ClickHouse 在 join 查询时不会主动发起谓词下推的操作,需要每个子查询提前完成过滤操作,需要注意的是,是否执行谓词下推,对性能影响差别很大(新版本中已经不存在此问题,但是需要注意谓词的位置的不同依然有性能的差异)
分布式表使用 GLOBAL
两张分布式表上的 IN 和 JOIN 之前必须加上 GLOBAL 关键字,右表只会在接收查询请求的那个节点查询一次,并将其分发到其他节点上。如果不加 GLOBAL 关键字的话,每个节点都会单独发起一次对右表的查询,而右表又是分布式表,就导致右表一共会被查询 N²次(N是该分布式表的分片数量),这就是查询放大,会带来很大开销
使用字典表
将一些需要关联分析的业务创建成字典表进行 join 操作,前提是字典表不宜太大,因为字典表会常驻内存
提前过滤
通过增加逻辑过滤可以减少数据扫描,达到提高执行速度及降低内存消耗的目的
七、数据一致性(重点)
对数据一致性支持最好的 Mergetree,也只是保证最终一致性:
我们在使用 ReplacingMergeTree、SummingMergeTree 这类表引擎的时候,会出现短暂数据不一致的情况。
在某些对一致性非常敏感的场景,通常有以下几种解决方案。
-
手动 OPTIMIZE
在写入数据后,立刻执行 OPTIMIZE 强制触发新写入分区的合并动作。
OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]] OPTIMIZE TABLE test_a FINAL;
-
通过 Group by 去重
数据并没有被真正的删除,而是被过滤掉了。在一些合适的场景下,可以结合 表级别的 TTL 最终将物理数据删除
-
通过 FINAL 查询
在查询语句后增加 FINAL 修饰符,这样在查询的过程中将会执行 Merge 的特殊逻辑(例如数据去重,预聚合等)。
FINAL 查询最终的性能和很多因素相关,列字段的大小、分区的数量等等都会影响到最终的查询时间,所以还要结合实际场景取舍。
八、物化视图
1、概念
- ClickHouse 的物化视图是一种预先计算并存储查询结果的数据对象,它可以提高查询性能,特别是对于复杂或频繁执行的查询。
- 物化视图是一种预先计算并存储查询结果的数据库对象。在 ClickHouse 等数据库系统中,当基础表的数据发生变化时,物化视图通常会有相应的机制来更新自身的数据,以反映基础表的最新状态。
- 在 ClickHouse 里,当基础表进行插入、更新或删除操作时,系统会通过后台的
Mutation
操作将这些变化应用到相关的物化视图中。例如,在基于orders
表创建的统计每个客户订单总数的物化视图里,若向orders
表插入一条新订单记录,物化视图会自动更新对应客户的订单总数。
2、物化视图与普通视图的区别
普通视图不保存数据,保存的仅仅是查询语句,查询的时候还是从原表读取数据,可以将普通视图理解为是个子查询。物化视图则是把查询的结果根据相应的引擎存入到了磁盘或内存中,对数据重新进行了组织,你可以理解物化视图是完全的一张新表。
3、优点
- 提高查询性能:通过提前计算和存储结果,避免了在每次查询时执行复杂的查询逻辑和大量的数据处理,显著减少了查询响应时间。特别是对于复杂的聚合查询、多表连接查询或需要频繁执行的查询,物化视图可以将查询结果缓存起来,直接返回结果,大大提高查询效率。
- 减轻数据库负载:由于物化视图分担了部分查询处理工作,使得数据库在处理查询请求时,无需每次都进行全量的数据扫描和计算,从而减轻了数据库服务器的 CPU、内存和 I/O 等资源的压力,提高了整个系统的并发处理能力。
- 数据本地化:物化视图可以将数据按照特定的需求进行本地化存储,对于分布式数据库系统,这有助于减少数据在网络中的传输,提高数据访问的局部性,进一步提升查询性能。
4、缺点
- 数据更新开销:当基础表的数据发生变化时,物化视图需要相应地进行更新以保持数据的一致性。这可能会带来额外的开销,包括计算资源、存储资源和时间成本。如果基础表的数据更新频繁,那么物化视图的更新操作可能会成为系统的瓶颈,影响整体性能。
- 存储空间占用:物化视图需要额外的存储空间来存储预先计算好的数据。对于大型数据集或多个物化视图的情况,可能会占用大量的磁盘空间,增加了存储成本。
- 维护复杂性:管理物化视图需要额外的工作,包括创建、维护和更新等操作。用户需要合理设计物化视图的更新策略,以平衡数据一致性和性能之间的关系。此外,在数据库架构发生变化或业务需求调整时,物化视图可能也需要相应地进行修改和调整,增加了系统的维护复杂性。
九、MaterializeMySQL 引擎
ClickHouse 20.8.2.3 版本增加了 MaterializeMySQL 引擎,以下是其相关介绍
- 功能特点:该引擎能将 MySQL 中的某个 database 映射到 ClickHouse,并自动在 ClickHouse 中创建对应的 ReplacingMergeTree,支持全量和增量同步。在 database 创建之初会全量同步 MySQL 中的表和数据,之后通过 binlog 进行增量同步,从而实现基于 MySQL Binlog 机制的业务数据库实时同步功能。
- 支持的操作:支持 insert、update、delete、alter、create、drop、truncate 等大部分 DDL 操作,以及 GTID 复制。
- 工作原理:通过监听 MySQL 的 binlog 事件,将其解析并转换为 ClickHouse 可处理的操作,然后应用到对应的 ReplacingMergeTree 表中。例如,当监听到 MySQL 的 insert、update 和 delete 事件时,会在 ClickHouse 的 database 内全局自增_version 字段,用于记录数据的版本;对于 delete 操作,会将_sign 字段的值更新为 - 1,实现伪删除。
- 优势:相比之前利用第三方中间件监听 binlog 事件的方式,该引擎减少了系统复杂度,提升了数据同步的时效性,能更好地将 OLTP 与 OLAP 业务融合,降低线上 MySQL 的负载,让 ClickHouse 承担起数据分析工作。
SET allow_experimental_database_materialize_mysql = 1;
CREATE DATABASE test_binlog ENGINE = MaterializeMySQL('host:3306','database','root','xxxxxx');
- 在查询时,对于已经被删除的数据,_sign = -1,ClickHouse 会自动重写 SQL,将 _sign = -1 的数据过滤掉;
- 对于修改的数据,则自动重写 SQL,为其增加 FINAL 修饰符。
- 在 mysql 执行删除表,此时在 clickhouse 处会同步删除对应表,如果查询会报错,mysql 新建表,clickhouse 可以查询到
十、常见问题排查
1、分布式 DDL 某数据节点的副本不执行
**问题:**使用分布式 ddl 执行命令 create table on cluster xxxx 某个节点上没有创建
表,但是 client 返回正常,查看日志有如下报错。
<Error> xxx.xxx: Retrying createReplica(), because some other replicas were created at the same time
**解决办法:**重启该不执行的节点
2、数据副本表和数据不一致
**问题:**由于某个数据节点副本异常,导致两数据副本表不一致,某个数据副本缺少表,需要将两个数据副本调整一致。
解决办法:
在缺少表的数据副本节点上创建缺少的表,创建为本地表,表结构可以在其他数据副本通过 show crete table xxxx 获取。
表结构创建后,clickhouse 会自动从其他副本同步该表数据,验证数据量是否一致即可。
3、副本节点全量恢复
**问题:**某个数据副本异常无法启动,需要重新搭建副本。
解决办法:
清空异常副本节点的 metadata 和 data 目录。
从另一个正常副本将 metadata 目录拷贝过来(这一步之后可以启动数据库,但是只有表结构没有数据)。
执行 sudo -u clickhouse touch /data/clickhouse/flags/force_restore_data
启动数据库。
4、数据副本启动缺少 zk 表
**问题:**某个数据副本表在 zk 上丢失数据,或者不存在,但是 metadata 元数据里
存在,导致启动异常,报错:
Can’t get data for node /clickhouse/tables/01-02/xxxxx/xxxxxxx/replicas/xxx/metadata: node doesn’t exist (No node): Cannot attach table xxxxxxx
解决办法:
-
metadata 中移除该表的结构文件,如果多个表报错都移除mv metadata/xxxxxx/xxxxxxxx.sql /tmp/
-
启动数据库
-
手工创建缺少的表,表结构从其他节点 show create table 获取。
-
创建后会自动同步数据,验证数据是否一致。
5、ZK table replicas 数据未删除,导致重建表报错
**问题:**重建表过程中,先使用 drop table xxx on cluster xxx ,各节点在 clickhouse 上table 已物理删除,但是 zk 里面针对某个 clickhouse 节点的 table meta 信息未被删除(低概率事件),因 zk 里仍存在该表的 meta 信息,导致再次创建该表 create table xxx on cluster, 该节点无法创建表(其他节点创建表成功),报错
Replica /clickhouse/tables/01-03/xxxxxx/xxx/replicas/xxx already exists..
解决办法:
从其他数据副本 cp 该 table 的 metadata sql 过来,重启节点。
6、Clickhouse 节点意外关闭
**问题:**模拟其中一个节点意外宕机,在大量 insert 数据的情况下,关闭某个节点
**现象:**数据写入不受影响、数据查询不受影响、建表 DDL 执行到异常节点会卡住,报错:
Code: 159. DB::Exception: Received from localhost:9000. DB::Exception: Watching task /clickhouse/task_queue/ddl/query-0000565925 is executing longer than distributed_ddl_task_timeout (=180) seconds. There are 1 unfinished hosts (0 of them are currently active), they are going to execute the query in background.
**解决办法:**启动异常节点,期间其他副本写入数据会自动同步过来,其他副本的建表 DDL 也会同步。
7、其他问题参考
ClickHouse的常见问题及解决方案_云数据库 ClickHouse(ClickHouse)-阿里云帮助中心
十一、监控以及数据备份
略
十二、总结
ai写的谨慎鉴别
ClickHouse 是俄罗斯 Yandex 于 2016 年开源的列式存储数据库,用 C++ 编写,主要用于 OLAP。以下是其核心要点总结:
1. 特性优势
- 列式存储:统计操作表现优,节省磁盘空间、提高压缩比。
- 功能丰富:覆盖大部分标准 SQL 语法,具备用户管理、权限管理、数据备份恢复等功能。
- 多样化引擎:有合并树、日志、接口和其他四大类 20 多种引擎。
- 高吞吐写入:采用类 LSM Tree 结构,顺序 append 写,写入性能优异,官方测试可达 50MB - 200MB/s。
- 数据分区与并行:单条查询可利用整机 CPU,但不利于多查询并发。
2. 操作使用
- 执行计划:使用
EXPLAIN [explain_mode] SELECT query;
查看,explain_mode
有SYNTAX
、PIPELINE
、AST
三种。 - 建表优化
- 数据类型:时间字段用
DateTime
,避免使用Nullable
类型。 - 分区和索引:分区粒度依业务而定,一般按天分区;必须指定索引列,筛选后数据百万以内最佳。
- 表参数:
Index_granularity
默认 8192,非必要不调整;可指定 TTL 管理历史数据。 - 写入和删除:避免单条或小批量操作,控制写入速度;写入过快报错可通过 WAL、调整内存配额等方式处理。
- 数据类型:时间字段用
- 常见配置
- CPU 资源:多项线程池大小建议设为 CPU 个数的 2 倍;
max_concurrent_queries
推荐 150 - 300;max_threads
默认是 CPU 核数。 - 内存资源:合理设置
max_memory_usage
、max_bytes_before_external_group_by
、max_bytes_before_external_sort
等参数;max_table_size_to_drop
建议改为 0。 - 存储:可挂载虚拟券组提升 I/O 性能,SSD 性能优于普通机械硬盘。
- CPU 资源:多项线程池大小建议设为 CPU 个数的 2 倍;
3. 语法与查询优化
- 语法优化:包括
COUNT
优化、消除子查询重复字段、谓词下推、聚合计算外推、聚合函数消除、删除重复的 Key、标量替换、三元运算优化等。
2,非必要不调整;可指定 TTL 管理历史数据。- 写入和删除:避免单条或小批量操作,控制写入速度;写入过快报错可通过 WAL、调整内存配额等方式处理。
- 常见配置
- CPU 资源:多项线程池大小建议设为 CPU 个数的 2 倍;
max_concurrent_queries
推荐 150 - 300;max_threads
默认是 CPU 核数。 - 内存资源:合理设置
max_memory_usage
、max_bytes_before_external_group_by
、max_bytes_before_external_sort
等参数;max_table_size_to_drop
建议改为 0。 - 存储:可挂载虚拟券组提升 I/O 性能,SSD 性能优于普通机械硬盘。
- CPU 资源:多项线程池大小建议设为 CPU 个数的 2 倍;
3. 语法与查询优化
- 语法优化:包括
COUNT
优化、消除子查询重复字段、谓词下推、聚合计算外推、聚合函数消除、删除重复的 Key、标量替换、三元运算优化等。 - 查询优化:单表查询可用
Prewhere
替代where
。