详解 ClickHouse 的建表优化

一、explain 查看执行计划

explain 功能是从 20.6 版本才成为正式的功能,之前的版本需要到 log 日志中查看执行过程

1. 基本语法

explain [plan | ast | syntax | pipeline] [setting1=value1, setting2=value2,...] select ... [format ...];
  • plan:默认查看模式,显示 sql 语句的执行计划
    • header 参数:打印计划中各个步骤的 head 说明,默认关闭,默认值 0
    • description 参数:打印计划中各个步骤的描述,默认开启,默认值 1
    • actions 参数:打印计划中各个步骤的详细信息,默认关闭,默认值 0
  • ast:查看语法树模式,不常使用
  • syntax:可查看优化语句,使用较多
  • pipeline:查看 PIPELINE 计划
    • header 参数:打印计划中各个步骤的 head 说明,默认关闭,默认值 0
    • graph 参数:用 DOT 图形语言描述管道图,默认关闭,需要查看相关的图形需要配合 graphviz 查看
    • actions 参数:如果开启了 graph,紧凑打印打,默认开启

2. 案例实操

  • 查看 plan

    explain [plan] select arrayJoin([1,2,3,null,null]);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;explain plan header=1, actions=1,description=1 select number from system.numbers limit 10;
    
  • 查看 ast

    explain AST SELECT number from system.numbers limit 10;
    
  • 查看 syntax

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

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

二、建表优化

1. 数据类型设置

1.1 时间类型字段
  • Hive 中建表时日期、时间字段一般存储为 String 类型,但在 ClickHouse 中建表时不建议

  • ClickHouse 中建表时日期、时间字段最好设置成对应的 Date 、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);create table t_type2(id UInt32,sku_id String,total_amount Decimal(16,2) ,create_time Datetime
    ) engine =ReplacingMergeTree(create_time)partition by toYYYYMMDD(create_time)-不需要转换primary key (id)order by (id, sku_id);
    
1.2 空值类型字段
  • ClickHouse 中使用 Nullable 来设置字段可以有空值,但是会拖累性能

  • 存储 Nullable 列时需要创建一个额外的文件来存储 NULL 的标记,增加消耗;Nullable 列无法被索引

    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;
    
  • 生产上建议:使用字段默认值或者在业务中无意义的值来表示空值

2. 分区和索引

  • 建表时要考虑设置分区,避免全表扫描,一般选择按天分区,如果不按天分区,则建议以单表一亿数据为例,分区大小控制在 10-30 个为最佳
  • 建表时必须指定 order by 字段,即索引、排序列;在指定多个索引列时将查询频率大的字段放最前面,然后基数特别大的字段不适合做索引列,如用户表的 userid 字段,通常筛选后的数据满足在百万以内为最佳

3. 表参数

  • Index_granularity 是用来控制索引粒度的,默认是 8192,如非必须不建议调整
  • 指定 TTL:对于不必须保存历史全量数据的表,建议指定对应的 TTL,可以免去手动过期历史数据的麻烦,TTL 也可以通过 alter table 语句随时修改

4. 写入和删除优化

  • 尽量不要执行单条或小批量删除和插入操作,这样会产生小分区文件,给后台 Merge 任务带来巨大压力
  • 不要一次写入太多分区,或数据写入太快,数据写入太快会导致 Merge 速度跟不上而报错,一般建议每秒钟发起 2-3 次写入操作,每次操作写入 2w~5w 条数据(依服务器性能而定)
  • 写入过快报错(Too many parts 和 Memory limit)处理:
    • “Too many parts 处理”:使用 WAL 预写日志,提高写入性能,in_memory_parts_enable_wal 默认为 true
    • 在服务器内存充裕的情况下增加内存配额,一般通过 max_memory_usage 来实现
    • 在服务器内存不充裕的情况下,建议将超出部分内容分配到系统硬盘上,但会降低执行速度,一般通过 max_bytes_before_external_group_by、max_bytes_before_external_sort 参数来实现

5. 常见配置

config.xml 配置项:https://clickhouse.tech/docs/en/operations/server-configuration-parameters/settings/
users.xml 配置项:https://clickhouse.tech/docs/en/operations/settings/settings/

5.1 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 核数
5.2 内存资源
配置描述
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,这样不管多大的分区表都可以删除
5.3 存储

ClickHouse 不支持设置多数据目录,为了提升数据 io 性能,可以挂载虚拟券组,一个券组绑定多块物理磁盘提升读写性能,多数据查询场景 SSD 会比普通机械硬盘快 2-3 倍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录一些可用的AI工具网站

记录一些可用的AI工具网站 AI对话大模型AI图片生成AI乐曲生成AI视频生成AI音频分离 AI对话大模型 当前时代巅峰,Microsoft Copilot:https://copilot.microsoft.com AI图片生成 stable diffusion模型资源分享社区,civitai:https…

更改ip后还被封是ip质量的原因吗?

不同的代理IP的质量相同,一般来说可以根据以下几个因素来进行判断: 1.可用率 可用率就是提取的这些代理IP中可以正常使用的比率。假如我们无法使用某个代理IP请求目标网站或者请求超时,那么就代表这个代理不可用,一般来说免费代…

mysql学习——SQL中的DQL和DCL

SQL中的DQL和DCL DQL基本查询条件查询聚合函数分组查询排序查询分页查询 DCL管理用户权限控制 学习黑马MySQL课程,记录笔记,用于复习。 DQL DQL英文全称是Data Query Language(数据查询语言),数据查询语言,用来查询数据库中表的记…

SpringSecurity-重写默认配置

重写UserDetailService组件 1.注入Bean的方式 /*** author: coffee* date: 2024/6/22 21:22* description: 重写springsecurity默认组件:注入Bean的方式*/Configuration public class ProjectConfig {/*** 重写userDetailsService组件*/Beanpublic UserDetailsSer…

【LC刷题】DAY12:226 144 94 145

【LC刷题】DAY12:226 144 94 145 文章目录 【LC刷题】DAY12:226 144 94 145226. 翻转二叉树 [link](https://leetcode.cn/problems/invert-binary-tree/)101. 对称二叉树 [link](https://leetcode.cn/problems/invert-binary-tree/description/)104. 二叉…

逆向学习数据库篇:多表查询技术详解

本节课在线学习视频(网盘地址,保存后即可免费观看): ​​https://pan.quark.cn/s/081e020c1f29​​ 在数据库管理中,多表查询是一种常见的操作,它允许我们从多个相关联的表中检索数据。这种查询通常涉及使…

Flowable更改默认数据库H2到Mysql数据库

Flowable更改默认数据库H2到Mysql数据库 1、下载flowable安装包,从官方下载,下载后解压缩 2、将flowable-ui.war包拷贝到tomcat里面的webapps目录,tomcat的安装在此就不熬术了。 3、此时启动tomcat,flowable-ui会使用默认的H2…

碳+绿证如何能源匹配?考虑碳交易和绿证交易制度的电力批发市场能源优化程序代码!

前言 近年来,面对日益受到全社会关注的气候变化问题,国外尤其是欧美等发达国家和地区针对电力行业制定了一系列碳减排组合机制。其中,碳排放权交易(以下简称“碳交易”)和绿色电力证书交易(以下简称“绿证…

【Docker】Docker简介_运行原理

1、简介 1.1基本概念 容器:容器是Docker的基本部署单元。它是一个轻量级的、独立的运行时环境,包含应用程序及其相关依赖。容器利用Linux内核的命名空间和控制组技术,实现了隔离性和资源管理,使得应用程序在不同的容器中运行不会…

ITREX大语言模型量化-优化工具

一、定义 定义demo 案例 二、实现 定义 ITREX 是Intel 提出的量化加速工具,https://github.com/intel/intel-extension-for-transformers 本实验基于英特尔大模型优化加速技术对大模型预测进行加速,常见的优化优化技术包括:量化&#xff08…

C++并发之协程实例(三)(co_await)

目录 1 协程2 实例3 运行 1 协程 协程(Coroutines)是一个可以挂起执行以便稍后恢复的函数。协程是无堆栈的:它们通过返回到调用方来暂停执行,并且恢复执行所需的数据与堆栈分开存储。这允许异步执行的顺序代码(例如,在没有显式回调…

前端面试题日常练-day81 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备,答案在文末 在Sass中,以下哪个功能用于创建一个颜色列表? a) extend b) for c) import d) color Sass中的父选择器(Parent Selector)是通过以下哪个符号表示的&…

【Oracle】实验一 安装和使用Oracle数据库

【实验目的】 掌握Oracle软件安装过程,选择安装组件掌握建立Oracle数据库,配置网络连接使用SQL*Plus,登录到实例和数据库掌握命令方式的关闭和启动实例及数据库 【实验内容】 安装Oracle19c,记录安装过程。切记:创建…

自然语言处理学习路线(1)——NLP的基本流程

NLP基本流程 【NLP基本流程】 0. 获取语料 ——> 1. 语料预处理 ——> 2. 特征工程&选择 ——> 3. 模型训练 ——> 4. 模型输出&上线 【NLP基本流程图】 Reference 1. 自然语言处理(NLP)的一般处理流程!-腾讯云开发者社区-腾讯云 2. …

js函数声明与函数表达式的区别

在JavaScript中,函数可以通过函数声明和函数表达式两种方式进行定义。 函数声明是通过关键字function和函数名来定义的,例如: function add(a, b) {return a b; }函数表达式是将函数赋值给一个变量或者存储在一个对象的属性中,…

数组初了解

一.引入 现在,有一个场景需求,我们需要将10个数字存入,也就是10个变量。但如果场景需求改变,是用户输入了10个数,让我们求里面的最大值。那10个变量就显得过于臃肿。 我们需要一个新的数据结构,来装一系列…

贪心推公式——AcWing 125. 耍杂技的牛

贪心推公式 定义 贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,希望通过局部的最优选择来得到全局最优解的算法策略。 运用情况 问题具有最优子结构,即一个问题的最优解包含其子问题的最优解。可以通过局部最优决策逐步推导到全局最优…

stm32学习笔记---GPIO输入(理论部分)

目录 GPIO输入模式下的硬件和电路 按键原理 传感器原理 什么是上下拉电阻? 运算放大器当做比较器 按键的硬件电路 传感器的硬件电路 STM32用到的C语言知识 STM32中的C语言数据类型 C语言中的宏定义 typedef和define的区别是什么? C语言的枚举…

计算机基础之:硬件系统的性能评估标准

服务器时钟的性能通常涉及多个方面,主要包括准确性、稳定性、以及对系统性能的影响。以下是一些关键指标和衡量方法: 准确性: 时间偏移:测量服务器时钟与一个可靠时间源(如GPS时间、原子钟或NTP服务器)之间…

Python itertools模块

itertools 是 Python 标准库中的一个模块,它提供了许多用于操作迭代对象的工具函数。这些函数可以高效地生成迭代器,用于处理序列和集合,特别适用于循环和组合数学。以下是 itertools 模块中一些常用函数的概述: 一、无限迭代器 i…