ClickHouse 语法优化规则
ClickHouse 的 SQL 优化规则是基于RBO(Rule Based Optimization),下面是一些优化规则
1 准备测试用表
1)上传官方的数据集
将visits_v1.tar和hits_v1.tar上传到虚拟机,解压到clickhouse数据路径下
// 解压到clickhouse数据路径
sudo tar -xvf hits_v1.tar -C /var/lib/clickhouse
sudo tar -xvf visits_v1.tar -C /var/lib/clickhouse//修改所属用户
sudo chown -R clickhouse:clickhouse /var/lib/clickhouse/data/datasets
sudo chown -R clickhouse:clickhouse /var/lib/clickhouse/metadata/datasets
2)重启clickhouse-server
sudo clickhouse restart
3)执行查询
clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1"
clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1"
注意:官方的tar包,包含了建库、建表语句、数据内容,这种方式不需要手动建库、建表,最方便。
hits_v1表有130多个字段,880多万条数据
visits_v1表有180多个字段,160多万条数据
2 COUNT 优化
在调用 count 函数时,如果使用的是 count() 或者 count(*),且没有 where 条件,则会直接使用 system.tables 的 total_rows,例如:
EXPLAIN SELECT count()FROM datasets.hits_v1;Union
Expression (Projection)
Expression (Before ORDER BY and SELECT)
MergingAggregated
ReadNothing (Optimized trivial count)
注意 Optimized trivial count ,这是对 count 的优化。
如果 count 具体的列字段,则不会使用此项优化:
EXPLAIN SELECT count(CounterID) FROM datasets.hits_v1;Union
Expression (Projection)
Expression (Before ORDER BY and SELECT)
Aggregating
Expression (Before GROUP BY)
ReadFromStorage (Read from MergeTree)
3 消除子查询重复字段
下面语句子查询中有两个重复的 id 字段,会被去重:
EXPLAIN SYNTAX SELECT
a.UserID,
b.VisitID,
a.URL,
b.UserID
FROM
hits_v1 AS a
LEFT JOIN (
SELECT
UserID,
UserID as HaHa,
VisitID
FROM visits_v1) AS b
USING (UserID)
limit 3;//返回优化语句:
SELECT
UserID,
VisitID,
URL,
b.UserID
FROM hits_v1 AS a
ALL LEFT JOIN
(
SELECT
UserID,
VisitID
FROM visits_v1
) AS b USING (UserID)
LIMIT 3
4 谓词下推
当group by有having子句,但是没有with cube、with rollup 或者with totals修饰的时候,having过滤会下推到where提前过滤。例如下面的查询,HAVING name变成了WHERE name,在group by之前过滤:
EXPLAIN SYNTAX SELECT UserID FROM hits_v1 GROUP BY UserID HAVING UserID = '8585742290196126178';//返回优化语句
SELECT UserID
FROM hits_v1
WHERE UserID = \'8585742290196126178\'
GROUP BY UserID
子查询也支持谓词下推:
EXPLAIN SYNTAX
SELECT *
FROM
(
SELECT UserID
FROM visits_v1
)
WHERE UserID = '8585742290196126178'//返回优化后的语句
SELECT UserID
FROM
(
SELECT UserID
FROM visits_v1
WHERE UserID = \'8585742290196126178\'
)
WHERE UserID = \'8585742290196126178\'
再来一个复杂例子:
//返回优化后的语句
SELECT UserID
FROM
(
SELECT UserID
FROM (
SELECT UserID
FROM visits_v1
WHERE UserID = \'8585742290196126178\')
WHERE UserID = \'8585742290196126178\'
UNION ALL
SELECT UserID
FROM (
SELECT UserID
FROM visits_v1
WHERE UserID = \'8585742290196126178\')
WHERE UserID = \'8585742290196126178\'
)
WHERE UserID = \'8585742290196126178\'
5 聚合计算外推
聚合函数内的计算,会外推,例如:
EXPLAIN SYNTAX
SELECT sum(UserID * 2)
FROM visits_v1//返回优化后的语句
SELECT sum(UserID) * 2
FROM visits_v1
6 聚合函数消除
如果对聚合键,也就是 group by key 使用 min、max、any 聚合函数,则将函数消除,例如:
EXPLAIN SYNTAX
SELECTsum(UserID * 2),max(VisitID),max(UserID)
FROM visits_v1
GROUP BY UserID//返回优化后的语句
SELECT sum(UserID) * 2,max(VisitID),
UserID
FROM visits_v1
GROUP BY UserID
7 删除重复的 order by key
例如下面的语句,重复的聚合键 id 字段会被去重:
EXPLAIN SYNTAX
SELECT *
FROM visits_v1
ORDER BY
UserID ASC,
UserID ASC,
VisitID ASC,
VisitID ASC//返回优化后的语句:
select
……
FROM visits_v1
ORDER BY
UserID ASC,
VisitID ASC
8 删除重复的 limit by key
例如下面的语句,重复声明的 name 字段会被去重:
EXPLAIN SYNTAX
SELECT *
FROM visits_v1
LIMIT 3 BY
VisitID,
VisitID
LIMIT 10//返回优化后的语句:
select
……
FROM visits_v1
LIMIT 3 BY VisitID
LIMIT 10
9 删除重复的 USING Key
例如下面的语句,重复的关联键 id 字段会被去重:
EXPLAIN SYNTAX
SELECT
a.UserID,
a.UserID,
b.VisitID,
a.URL,
b.UserID
FROM hits_v1 AS a
LEFT JOIN visits_v1 AS b USING (UserID, UserID)//返回优化后的语句:
SELECT
UserID,
UserID,
VisitID,
URL,
b.UserID
FROM hits_v1 AS a
ALL LEFT JOIN visits_v1 AS b USING (UserID)
10 标量替换
如果子查询只返回一行数据,在被引用的时候用标量替换,例如下面语句中的 total_disk_usage 字段:
EXPLAIN SYNTAX
WITH (
SELECT sum(bytes)
FROM system.parts
WHERE active) AS total_disk_usage
SELECT(sum(bytes) / total_disk_usage) * 100 AS table_disk_usage,
table
FROM system.parts
GROUP BY table
ORDER BY table_disk_usage DESC
LIMIT 10;//返回优化后的语句:
WITH CAST(0, \'UInt64\') AS total_disk_usage
SELECT (sum(bytes) / total_disk_usage) * 100 AS table_disk_usage,
table
FROM system.parts
GROUP BY table
ORDER BY table_disk_usage DESC
LIMIT 10
11 三元运算优化
如果开启了 optimize_if_chain_to_multiif 参数,三元运算符会被替换成 multiIf 函数,例如:
EXPLAIN SYNTAX
SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 'atguigu')
FROM numbers(10)
settings optimize_if_chain_to_multiif = 1;// 返回优化后的语句:
SELECT multiIf(number = 1, \'hello\', number = 2, \'world\', \'atguigu\')
FROM numbers(10)
SETTINGS optimize_if_chain_to_multiif = 1
相关文章:
ClickHouse 语法优化规则
ClickHouse 的 SQL 优化规则是基于RBO(Rule Based Optimization),下面是一些优化规则 1 准备测试用表 1)上传官方的数据集 将visits_v1.tar和hits_v1.tar上传到虚拟机,解压到clickhouse数据路径下 // 解压到clickhouse数据路径 sudo tar -xvf…...
3-运行第一个docker image-hello world
CentOS7.9下安装完成docker后,我们开始部署第一个docker image-hello world 1.以root用户登录CentOS7.9服务器,拉取centos7 images 命令: docker pull hello-world [root@centos79 ~]# docker pull hello-world Using default tag: latest latest: Pulling from library…...

【漏洞复现】泛微e-Weaver SQL注入
漏洞描述 泛微e-Weaver(FANWEI e-Weaver)是一款广泛应用于企业数字化转型领域的集成协同管理平台。作为中国知名的企业级软件解决方案提供商,泛微软件(广州)股份有限公司开发和推广了e-Weaver平台。 泛微e-Weaver旨在…...

「git 系列」git 如何存储代码的?
这里写自定义目录标题 git 文件存储位置git 数据模型示例分析分析前准备命令哈希值 具体示例 不同版本的提交,git 做了什么工作?snapshot vs delta-based vs backup参考资料 git 文件存储位置 想要了解如何存储,首先需要知道存储位置。 当我…...

IDEA 集成 Docker 插件一键部署 SpringBoot 应用
目录 前言IDEA 安装 Docker 插件配置 Docker 远程服务器编写 DockerFileSpringBoot 部署配置SpringBoot 项目部署结语 前言 随着容器化技术的崛起,Docker成为了现代软件开发的关键工具。在Java开发中,Spring Boot是一款备受青睐的框架,然而&…...

IDEA无法查看源码是.class,而不是.java解决方案?
问题:在idea中,ctrl鼠标左键进入源码,但是有时候会出现无法查看反编译的源码,如图! 而我们需要的是方法1: mvn dependency:resolve -Dclassifiersources 注意:需要该模块的目录下,不是该文件目…...

机器视觉系统选型-定光照强度
同一个外形结构的光源,光照强度受如下影响: 单颗灯珠的亮度灯珠排列的数量和密度漫射板/防护板的材质(透明、半透明、全漫射) 在合理范围内提升光照强度,可降低对相机曝光时长的要求 外形结构尺寸相同的两款光源&am…...

ChatGLM3-6B:新一代开源双语对话语言模型,流畅对话与低部署门槛再升级
项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实…...

StoneDB顺利通过中科院软件所 2023 开源之夏 结项审核
近日,中科院软件所-开源软件供应链点亮计划-开源之夏2023的结项名单正式出炉,经过三个月的项目开发和一个多月的严格审核,共产生 418个成功结项项目!其中,StoneDB 作为本次参与开源社区,社区入选的两个项目…...

Linux本地docker一键部署traefik+内网穿透工具实现远程访问Web UI管理界面
文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件,能轻易的部署微服务。它支持多种后端 (D…...

SpringCloud FeignClient声明式服务调用采坑记录(A调用服务B/C,B/C重启后必须重启A后才能成功调用配置项)
SpringCloud FeignClient声明式服务调用(A调用服务B/C,B/C重启后必须重启A后才能成功调用配置项采坑记录) 1. 报错(info级别的警告信息)2. 原因:使用了默认了cache负载均衡,或者禁用了ribbonLoa…...

安装银河麒麟linux系统docker(docker-compose)环境,注意事项(一定能解决,有环境资源)
1:安装docker环境必须使用麒麟的版本如下 2:使用docker-compse up -d启动容器遇到的文件 故障1:如果运行docker-compose up 报“Cannot create redo log files because data files are corrupt or the database was not shut down cleanly a…...

BUG:编写springboot单元测试,自动注入实体类报空指针异常
原因:修饰测试方法的Test注解导入错误 造成错误的原因是 import org.junit.Test;正确的应该是 import org.junit.jupiter.api.Test前者是Junit4,后者是Junit5 junit4的使用似乎要在测试类除了添加SpringbootTest还要添加RunWith(SpringRunner.class) 同时要注意spring-boot-s…...
深度解析 InterpretML:打开机器学习模型的黑箱
深度解析 InterpretML:打开机器学习模型的黑箱 机器学习模型的高性能往往伴随着模型的复杂性,这使得模型的决策过程变得不透明,难以理解。在这个背景下,可解释性机器学习成为了一个备受关注的领域。本文将介绍 InterpretML&#…...

数据结构初阶leetcodeOJ题(二)
目录 第一题 思路: 第二题 思路 第三题 描述 示例1 思路 总结:这种类似的题,都是用快慢指针,相差一定的距离然后输出慢指针。 第一题 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val…...

若依框架数据源切换为pg库
一 切换数据源 在ruoyi-admin项目里引入pg数据库驱动 <dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.2.18</version> </dependency>修改配置文件里的数据源为pg spring:d…...

java 访问sqlserver 和 此驱动程序不支持jre1.8错误
sqlserver数据如下; TestSQL.java; import java.sql.*;public class TestSQL {public static void main(String[] args) throws ClassNotFoundException, SQLException {String driverName "com.microsoft.sqlserver.jdbc.SQLServerDriver";…...

C/C++字符判断 2021年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
目录 C/C字符判断 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C字符判断 2021年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 对于给定的字符,如果该字符是大小写字母或…...
Kotlin语言实现单击任意TextVIew切换一个新页面,并且实现颜色变换
<LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:orientation"vertical"android:layout_height"match_parent"><!-- 这里放置你的其他视图组件 -->&…...

Flume学习笔记(4)—— Flume数据流监控
前置知识: Flume学习笔记(1)—— Flume入门-CSDN博客 Flume学习笔记(2)—— Flume进阶-CSDN博客 Flume 数据流监控 Ganglia 的安装与部署 Ganglia 由 gmond、gmetad 和 gweb 三部分组成。 gmond(Ganglia …...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...