ClickHouse进阶(七):Clickhouse数据查询-1

进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容!

🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客

📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情!

👍点赞:赞同优秀创作,你的点赞是对我创作最大的认可!

⭐️ 收藏:收藏原创博文,让我们一起打造IT界的荣耀与辉煌!

✏️评论:留下心声墨迹,你的评论将是我努力改进的方向!

 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频


目录

​​​​​​​1. with子句

1.1 定义变量

1.2 调用函数

1.3 定义子查询

1.4 在子查询中重复使用with

2. From子句

​​​​​​​3. Sample子句

3.1 Sample factor

3.2 Sample rows

3.3 SAMPLE factor OFFSET n

​​​​​​​4. Array Join子句


可以从官网下载官网提供的数据集hits_v1和visits_v1,对应的下载路径为:https://datasets.clickhouse.com/hits/partitions/hits_v1.tar和https://datasets.clickhouse.com/visits/partitions/visits_v1.tar,下载之后对应两个压缩包:

hits_v1.tarvisits_v1.tar

将以上两个压缩包进行上传到node1节点/softwar目录下,并解压到目录”/var/lib/clickhouse”中。

[root@node1 ~]# cd /software/[root@node1 software]# tar xvf hits_v1.tar -C /var/lib/clickhouse[root@node1 software]# tar xvf visits_v1.tar -C /var/lib/clickhouse

重启node1节点上的clickhouse,查询数据:

[root@node1 ~]# service clickhouse-server restart[root@node1 ~]# clickhouse-clientnode1 :) show databases;┌─name─────┐│ datasets ││ default  ││ system   │└──────────┘#查询表 hits_v1中的数据量node1 :) select count(*) from datasets.hits_v1;┌─count()─┐│ 8873898 │└─────────┘#查询表 visits_v1中的数据量node1 :) select count(*) from datasets.visits_v1;┌─count()─┐│ 1676861 │└─────────┘

clickhouse完全使用SQL作为查询语言,能够以Selete查询语句从数据库中查询数据,虽然clickhouse拥有优秀的查询性能,但是我们也不能滥用查询,掌握clickhouse支持的各种查询子句很有必要,使用不恰当的SQL语句进行查询不仅带来低性能,还可能带来系统不可预知的错误。例如:我们使用select * 查询数据时,通配符*对列式存储的clickhouse没有一点好处,针对一张拥有133个列的数据表hits_v1,查询2000行数据时,使用*与不使用*速度相差几乎300倍:

#使用*查询2000行数据node1 :) select * from datasets.hits_v1 limit 2000;2000 rows in set. Elapsed: 4.306 sec. Processed 2.00 thousand rows, 2.23 MB (464.50 rows/s., 518.76 KB/s.)#不使用*查询2000行数据node1 :) select WatchID from datasets.hits_v1 limit 2000;2000 rows in set. Elapsed: 0.016 sec. Processed 2.00 thousand rows, 16.00 KB (126.48 thousand rows/s., 1.01 MB/s.)

此外需要注意,clickhouse中对字段的解析大小写敏感,select a与select A表示的语义不同,下面我们学习下clickhouse中支持的查询语句。

​​​​​​​​​​​​​​1. with子句

clickhouse支持with子句以增强语句的表达,例如如下查询:

node1 :) SELECT pow(pow(2,2),3)┌─pow(pow(2, 2), 3)─┐│                64 │└───────────────────┘

我们可以通过使用with子句进行简化,提高可读性:

node1 :) WITH pow(2,2) AS a SELECT power(a,3)┌─pow(a, 3)─┐│        64 │└───────────┘

with的使用支持如下四种用法:

1.1 定义变量

可以通过with定义变量,这些变量在后续的查询子句中可以直接访问。例如:

node1 :) WITH 10 AS startSELECT numberFROM system.numbersWHERE number > startLIMIT 5┌─number─┐│     11 ││     12 ││     13 ││     14 ││     15 │└────────┘

1.2 调用函数

可以访问select子句中的列字段,并调用函数做进一步处理,处理之后的数据可以在select子句中继续使用。例如:

node1 :) WITH SUM(data_uncompressed_bytes) AS bytesSELECTdatabase,formatReadableSize(bytes) AS formatFROM system.columnsGROUP BY databaseORDER BY bytes DESC┌─database─┬─format─────┐│ datasets │ 7.40 GiB   ││ system   │ 197.27 MiB ││ default  │ 0.00 B     │└──────────┴────────────┘

1.3 定义子查询

可以使用with定义子查询,例如,借助子查询可以得出各database未压缩数据大小与数据总和大小的比例排名:

node1 :) WITH (SELECT SUM(data_uncompressed_bytes)FROM system.columns) AS total_bytesSELECTdatabase,(SUM(data_uncompressed_bytes) / total_bytes) * 100 AS database_disk_usageFROM system.columnsGROUP BY databaseORDER BY database_disk_usage DESC┌─database─┬─database_disk_usage─┐│ datasets │   97.31767735000648 ││ system   │   2.682322649993527 ││ default  │                   0 │└──────────┴─────────────────────┘

注意:在with中使用子查询时智能返回一行数据,如果结果集大于一行则报错。

1.4 在子查询中重复使用with

在子查询中可以嵌套使用With子句,例如,在计算出各database未压缩数据大小与数据总和的比例之后,又进行取整函数操作:

node1 :) WITH round(database_disk_usage) AS database_disk_usage_v1SELECTdatabase,database_disk_usage,database_disk_usage_v1FROM(WITH (SELECT SUM(data_uncompressed_bytes)FROM system.columns) AS total_bytesSELECTdatabase,(SUM(data_uncompressed_bytes) / total_bytes) * 100 AS database_disk_usageFROM system.columnsGROUP BY databaseORDER BY database_disk_usage DESC)┌─database─┬─database_disk_usage─┬─database_disk_usage_v1─┐│ datasets │    97.2911778785499 │                     97 ││ system   │  2.7088221214500954 │                      3 ││ default  │                   0 │                      0 │└──────────┴─────────────────────┴────────────────────────┘

2. From子句

From子句表示从何处读取数据,支持2种形式,由于From比较简单,这里不再举例,2种使用方式如下:

SELECT clo1 FROM tbl;
SELECT rst FROM (SELECT sum(col1) as rst FROM tbl)

from 关键字可以省略,此时会从虚拟表中取数,clickhouse中没有dual虚拟表,它的虚拟表是system.one,例如,以下两种查询等价:

SELECT 1;SELECT 1 FROM system.one;

另外,FROM 子句后还可以跟上final修饰符,可以配合COllapsingMergeTree和VersionedCollapsingMergeTree等表引擎进行查询操作,强制在查询过程中合并,由于Final修饰符会降低查询性能,所以尽量避免使用Final修饰符。

​​​​​​​3. Sample子句

Sample子句可以实现数据采样功能,使查询仅返回采样数据而非全部数据,从而减少查询负载。Sample采样机制是幂等机制,也就是说在数据不发生变化,使用相同的采样规则总是能够返回相同的数据。

sample子句只能用于MergeTree系列表引擎,并且要求在Create Table时声明sample by 抽样表达式。

例如,创建表 tbl 声明sample by抽样表达式:

CREATE TABLE tbl(id UInt32,name String,age UInt32,birthday DATE)ENGINE = MERGETREE()PARTITION BY toYYYYMM(birthday)ORDER BY (id,intHash32(age))SAMPLE BY intHash32(age)

以上创建sample by 采样表时注意:

  1. Sample by 所声明的表达式必须同时包含在主键的声明内。
  2. Sample Key 必须是Int类型,虽然在建表不报错,但是数据查询时报错。

另外,建表时没有声明Sample by,在使用sample 采样时会报错。

Sample目前支持三种语法,前面导入的datasets.hits_v1创建时指定了SAMPLE BY ,建表语句如下:

CREATE TABLE datasets.hits_v1(`WatchID` UInt64,`JavaEnable` UInt8,`Title` String,... ...)ENGINE = MergeTree()PARTITION BY toYYYYMM(EventDate)ORDER BY (CounterID, EventDate, intHash32(UserID))SAMPLE BY intHash32(UserID)

下面就以表hits_v1为例,来讲解sample三种用法。

3.1 Sample factor

Sample factor表示按因子系数采样,factor表示采样因子,取值0-1之间的小数,表示采样总体数据的比例。如果factor 设置为0或者1,则表示不采样。使用如下:

#按10%的因子采样数据
SELECT CounterID FROM datasets.hits_v1 SAMPLE 0.1;
839889 rows in set. Elapsed: 0.114 sec. Processed 7.36 million rows, 88.30 MB (64.46 million rows/s., 773.46 MB/s.)

3.2 Sample rows

Sample rows表示按照样本数量采样,其中rows表示大概采样多少行数据,是个近似值,取值必须大于1,如果rows行数大于表总数,效果等同于rows=1,即不采样。使用如下:

node1 :) SELECT count() FROM datasets.hits_v1 SAMPLE 10000;┌─count()─┐│    9251 │└─────────┘

3.3 SAMPLE factor OFFSET n

SAMPLE factor OFFSET n 表示按因子系数和偏移量采样,其中factor表示采样因子,即采样总数据的百分比,n表示偏移多少数据后才开始采样,它们两个取值都是0~1之间的小数。使用如下:

#偏移量0.5并按0.4的系数采样node1 :) SELECT CounterID FROM datasets.hits_v1 SAMPLE 0.4 OFFSET 0.5;3589194 rows in set.

偏移量0.5并按0.4的系数采样的采样为:从数据的二分之一处开始,按总数量的0.4采样数据。如果Sample比例采样出现了溢出,则数据会被自动截断,例如:

node1 :) SELECT CounterID FROM datasets.hits_v1 SAMPLE 0.4 OFFSET 0.9;892694 rows in set.

​​​​​​​4. Array Join子句

Array join 子句允许在数据表的内部,与数组类型的字段进行join操作,从而将一行数组展开为多行。

首先我们创建一张 MergeTree引擎表并加入数据,操作如下:

#创建表 mr_tblnode1 :) CREATE TABLE mr_tbl(`id` UInt8,`name` String,`age` Int,`local` Array(String))ENGINE = MergeTree()ORDER BY id#向表mr_tbl中插入数据node1 :) insert into table mr_tbl values (1,'zs',18,['beijing','shanghai']),(2,'ls',19,['guangzhou','hangzhou']),(3,'ww',20,[]);┌─id─┬─name─┬─age─┬─local────────────────────┐│  1 │ zs   │  18 │ ['beijing','shanghai']   ││  2 │ ls   │  19 │ ['guangzhou','hangzhou'] ││  3 │ ww   │  20 │ []                       │└────┴──────┴─────┴──────────────────────────┘

我们可以使用array join针对以上表数组字段一条膨胀成多条数据,类似Hive中的explode函数,在clickhouse中没有explode函数,可以使用array join 达到同样效果。

在使用Array join时,一条select语句中只能存在一个Array join(使用嵌套子查询除外),目前支持INNER和LEFT两种JOIN策略:

  • INNER ARRAY JOIN

Array join 默认使用的就是INNER JOIN 策略,使用如下:

node1 :) SELECT id,name,age,local FROM mr_tbl ARRAY JOIN local;┌─id─┬─name─┬─age─┬─local─────┐│  1 │ zs   │  18 │ beijing   ││  1 │ zs   │  18 │ shanghai  ││  2 │ ls   │  19 │ guangzhou ││  2 │ ls   │  19 │ hangzhou  │└────┴──────┴─────┴───────────┘

从以上查询结果来看,数据由原来的一行根据local列变成多行,并且排除掉了空数组对应的行。在使用Array Join时,如果我们在膨胀之后的数据结果中能够访问原有数组字段可以使用如下方式查询:

node1 :) SELECT id,name,age,local ,v FROM mr_tbl ARRAY JOIN local AS v;┌─id─┬─name─┬─age─┬─local────────────────────┬─v─────────┐│  1 │ zs   │  18 │ ['beijing','shanghai']   │ beijing   ││  1 │ zs   │  18 │ ['beijing','shanghai']   │ shanghai  ││  2 │ ls   │  19 │ ['guangzhou','hangzhou'] │ guangzhou ││  2 │ ls   │  19 │ ['guangzhou','hangzhou'] │ hangzhou  │└────┴──────┴─────┴──────────────────────────┴───────────┘
  • LEFT ARRAY JOIN

Array Join 子句支持LEFT连接策略,Left array join不会排除空数组,执行如下语句并查看结果。

node1 :) SELECT id,name,age,local FROM mr_tbl LEFT ARRAY JOIN local;┌─id─┬─name─┬─age─┬─local─────┐│  1 │ zs   │  18 │ beijing   ││  1 │ zs   │  18 │ shanghai  ││  2 │ ls   │  19 │ guangzhou ││  2 │ ls   │  19 │ hangzhou  ││  3 │ ww   │  20 │           │└────┴──────┴─────┴───────────┘

当同时对多个数组字段进行Array join 操作时,array join 对应的多个字段的数组长度必须相等,查询的计算逻辑是按行合并并不是产生笛卡尔积,举例如下:

#创建表 mr_tbl2node1 :) CREATE TABLE mr_tbl2(`id` UInt8,`name` String,`age` Int,`local` Array(String),`score` Array(UInt32))ENGINE = MergeTree()ORDER BY id#向表mr_tbl2中插入以下数据node1 :) insert into table mr_tbl2 values (1,'zs',18,['beijing','shanghai'],[100,200]),(2,'ls',19,['guangzhou','hangzhou'],[300,400]),(3,'ww',20,[],[]);┌─id─┬─name─┬─age─┬─local────────────────────┬─score─────┐│  1 │ zs   │  18 │ ['beijing','shanghai']   │ [100,200] ││  2 │ ls   │  19 │ ['guangzhou','hangzhou'] │ [300,400] ││  3 │ ww   │  20 │ []                       │ [] │└────┴──────┴─────┴──────────────────────────┴───────────┘#执行array join 语句,将数组中的数据一变多行node1 :) select id,name,age,local,local2,score,score2 from mr_tbl2 left array join local as local2 ,score as score2;


👨‍💻如需博文中的资料请私信博主。


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

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

相关文章

SpringMVC应用

文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…

11.Redis的慢操作之rehash

Redis为什么快 它接收到一个键值对操作后,能以微秒级别的速度找到数据,并快速完成操作。 数据库这么多,为啥 Redis 能有这么突出的表现呢? 内存数据结构 一方面,这是因为它是内存数据库,所有操作都在内存上…

查看mysql数据库的charset和collation

SELECT * FROM information_schema.SCHEMATA WHERE schema_name test_data; 发现: chaset是utf8mb4,collation是utf8mb4_generic_ci 可笑的是我导入sql脚本,要把脚本中所有的utf8mb4改为utf8,将utf8mb4_generic_ci为utf8_unico…

React 开发一个移动端项目(1)

技术栈: 项目搭建:React 官方脚手架 create-react-appreact hooks状态管理:redux 、 redux-thunkUI 组件库:antd-mobileajax请求库:axios路由:react-router-dom 以及 historyCSS 预编译器:sass…

SpringBoot 拦截org.thymeleaf.exceptions.TemplateInputException异常

SpringBoot 拦截thymeleaf异常 org.thymeleaf.exceptions.TemplateInputException异常 org.thymeleaf.exceptions.TemplateProcessingE xception: Could not parse as each: "message : xxx " (template: “xxxx” - line xx, col xx) thymeleaf异常复现 你是故意的…

Vue3,Typescript中引用组件路径无法找到模块报错

是这么个事,我在vue3新创建的项目里,写了个组件叫headerIndex.vue,放到app.vue中import就会报错 路径肯定没写错,找到了解决方法,但是也没想明白为什么 解决方法如下 在vite-env.d.ts文件中加入 declare module &qu…

内网隧道代理技术(二十三)之 DNS隧道反弹Shell

DNS隧道反弹Shell DNS隧道 DNS协议是一种请求、应答协议,也是一种可用于应用层的隧道技术。DNS隧道的工作原理很简单,在进行DNS查询时,如果查询的域名不在DNS服务器本机缓存中,就会访问互联网进行查询,然后返回结果。如果在互联网上有一台定制的服务器,那么依靠DNS协议…

Vue进阶(贰幺幺)CVE-2020-11022/CVE-2020-11023漏洞解析

文章目录 一、前言二、漏洞原理三、修复方案3.1 升级jQuery3.2 1.x 升级至 3.x 需要考虑的问题3.2.1 table表格元素自动添加tbody3.2.2 方法变更 3.3 jquery migrate是什么 四、拓展阅读 一、前言 代码安全扫描阶段,前端资源审计发现jQuery版本过低导致生产系统存在…

(二十六)大数据实战——kafka集群之Kraft模式安装与部署

前言 本节内容主要介绍kafka3.0版本以后,一种新的kafka集群搭建模式看kraft,在该模式下,kafka高可用不在依赖于zookeeper,用 controller 节点代替 zookeeper,元数据保存在 controller 中,由 controller 直…

解决transform带来的z-index失效问题

现象如下: 其实下拉列表已经设置了z-index: 但是为什么z-index没有生效呢。 后来发现原来它的父级元素使用了transform进行垂直方向居中 网上查询了相关资料,说: tranform由于会构造一个新的context层, 然后这个层的z轴优先级会最低巴拉巴拉的&#xff…

【python零基础入门学习】python基础篇之文件对象open、模块以及函数的使用(三)

本站以分享各种运维经验和运维所需要的技能为主 《python》:python零基础入门学习 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…

【C++】string类模拟实现上篇(附完整源码)

目录 前言1. string的基本结构2. 构造函数、析构函数2.1 构造函数的实现2.1.1带参构造函数 2.2析构函数2.3无参构造函数2.4无参和带参构造函数合并 3. string的遍历3.1 operator[ ]3.2迭代器模拟实现 (简单实现)3.3 const迭代器模拟实现 4. 数据的增删查改4.1 reser…

2、在Windows 10中安装和配置 PostgreSQL 15.4

一、PostgreSQL 安装前简介 PostgreSQL(通常简称为PG SQL)是一个强大、开源的关系型数据库管理系统(DBMS),它具有广泛的功能和可扩展性,被广泛用于企业和开发项目中,PostgreSQL 具有如下一些关键特点&…

【云原生系列】Docker学习

目录 一、Docker常用命令 1 基础命令 2 镜像命令 2.1 docker images 查看本地主机的所有镜像 2.2 docker search 搜索镜像 2.3 docker pull 镜像名[:tag] 下载镜像 2.4 docker rmi 删除镜像 2.5 docker build 构建镜像 3 容器命令 3.1 如拉取一个centos镜像 3.2 运行…

SpringMVC的常用注解,参数传递以及页面跳转的使用

目录 slf4j 常用注解 RequestMapping RequestParam RequestBody PathVariable 参数传递 首先在pom.xml配置文件中导入SLF4J的依赖 基础类型String 复杂类型 RequestParam PathVariable RequestBody 增删改查 返回值 void返回值 String返回值 modelString …

51单片机的简易篮球计分器倒计时仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机的简易篮球计分器倒计时仿真设计( proteus仿真程序原理图报告讲解视频) 1.主要功能:2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接 51单片机的简易篮球计分器倒计时仿真设计( proteus仿真程序原理图报告讲解视频…

List常见面试问题

List的特点有哪些? Java中的List是一种存放有序的、可以重复的数据的集合,它允许重复元素的存在。List中的元素都有对应的一个序列号(索引)记录着元素的位置,因此可以通过这个序列号来访问元素。 ‍ Java中集合有哪些? Java中…

最新仿闲鱼链接+独立后台管理 跳转APP

2024最新仿xy链接源码 后台一键生成链接,后台管理教程:解压源码,修改数据库config/Congig 不会可以看源码里有教程 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)

前言: 本文是对于动态内存管理知识后续的补充,以及加深对其的理解。对于动态内存管理涉及的大部分知识在这篇文章中 ---- 【C进阶】 动态内存管理_Dream_Chaser~的博客-CSDN博客 本文涉及的知识内容主要在两方面: 简单解析C/C程序…

CSS中如何实现一个自适应正方形(宽高相等)的元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐利用padding百分比⭐2. 利用::before伪元素⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对W…