clickhouse笔记(入门+部分进阶)

文章目录

  • ClickHouse学习笔记
    • 一、ClickHouse的安装
      • 准备工作
        • 1.确定防火墙处于关闭状态
        • 2.CentOS取消打开文件数限制
        • 3.安装依赖
        • 4.CendtOS取消SELINUX
      • 安装
        • 1.将文件传到clickhouse目录下,并安装
        • 2.修改配置文件
      • 简单使用clickhouse
    • 二、数据类型
      • 整型
      • 浮点型
      • Decimal 型
      • 字符串
      • 枚举类型
      • 时间类型
      • 数组
    • 三、表引擎
      • TinyLog
      • Memory
      • MergeTree
      • partition by 分区(可选)
      • primary key 主键(可选)
      • order by(必选)
      • 二级索引
      • 数据 TTL
      • ReplacingMergeTree
      • SummingMergeTree
    • 四、SQL操作
      • 5.1 Insert
      • 5.2 Update 和 Delete
      • 5.3 查询操作
      • alter 操作
  • 高级
    • 五、Explain查看执行计划
      • 基本语法
        • PLAN:用于查看执行计划,默认值。
        • ➢ AST :用于查看语法树;
        • ➢ SYNTAX:用于优化语法;
        • ➢ PIPELINE:用于查看 PIPELINE 计划。
      • 实例操作
        • 简单查询
        • 复杂SQL的执行计划
        • 打开全部执行计划
        • 1)AST 语法树
        • 2)SYNTAX 语法优化
        • 4)查看 PIPELINE

ClickHouse学习笔记

一、ClickHouse的安装

准备工作

1.确定防火墙处于关闭状态

2.CentOS取消打开文件数限制

(1)在 hadoop103 的 /etc/security/limits.conf 文件的末尾加入以下内容

[root@hadoop103 ~]$ sudo vim /etc/security/limits.conf

* soft nofile 65536 

* hard nofile 65536 

* soft nproc 131072 

* hard nproc 131072

clickhouse笔记(入门+部分进阶)_第1张图片

(2)在 hadoop103 的/etc/security/limits.d/20-nproc.conf 文件的末尾加入以下内容

[atguigu@hadoop102 ~]$ sudo vim /etc/security/limits.d/20-nproc.conf

* soft nofile 65536 

* hard nofile 65536 

* soft nproc 131072 

* hard nproc 131072

(3)将上面2个文件分发到其它2个虚拟机上

3.安装依赖

执行命令 安装依赖
[root@hadoop103 security]# xcall   yum install -y libtool

[root@hadoop103 security]# xcall yum install -y *unixODBC*

4.CendtOS取消SELINUX

[root@hadoop103 security]# vim /etc/selinux/config

修改配置文件

SELINUX=disabled

之后分发给其它3台虚拟机

后重启

使用

getenforce指令可查询当前selinu情况
[root@hadoop103 ~]# getenforce
Disabled

clickhouse笔记(入门+部分进阶)_第2张图片

安装

1.将文件传到clickhouse目录下,并安装

在soft目录下创建clickhouse目录,将安装包全部移动到其下,

分发给另外2台虚拟机

之后执行命令安装

[root@hadoop103 clickhouse]# rpm -ivh *.rpm

查看是否安装完成

[root@hadoop103 clickhouse]# rpm -qa|grep clickhouse

在这里插入图片描述

bin/  ===> /usr/bin/
conf/ ===> /etc/clickhouse-server/
lib/  ===> /var/lib/clickhouse
log/  ===> /var/log/clickhouse

2.修改配置文件

[root@hadoop103 clickhouse]# cd /etc/clickhouse-server/
[root@hadoop103 clickhouse-server]# ll
总用量 64
dr-x------ 2 clickhouse clickhouse     6 83 07:29 config.d
-r-------- 1 clickhouse clickhouse 56029 714 00:55 config.xml
dr-x------ 2 clickhouse clickhouse    34 83 07:29 users.d
-r-------- 1 clickhouse clickhouse  6053 714 00:55 users.xml
[root@hadoop103 clickhouse-server]# pwd
/etc/clickhouse-server
[root@hadoop103 clickhouse-server]# vim config.xml 

在这里插入图片描述

简单使用clickhouse

启动server

clickhouse start
restart  //重启
[root@hadoop103 clickhouse-server]# clickhouse-client -m 

如果设置密码的话会报错

Code: 497. DB::Exception: Received from localhost:9000. DB::Exception: default: Not enough privileges. To execute this query it's necessary to have grant SHOW USERS ON *.*. 

需要在每一条命令后加上

--password 你的密码

[root@hadoop103 clickhouse-server]# clickhouse-client --password 你的密码

二、数据类型

整型

固定长度的整型,包括有符号整型或无符号整型。

整型范围(-2n-1~2n-1-1):

Int8 - [-128 : 127]

Int16 - [-32768 : 32767]

Int32 - [-2147483648 : 2147483647]

Int64 - [-9223372036854775808 : 9223372036854775807]

无符号整型范围(0~2n-1):

UInt8 - [0 : 255]

UInt16 - [0 : 65535]

UInt32 - [0 : 4294967295]

UInt64 - [0 : 18446744073709551615]

使用场景: 个数、数量、也可以存储型 id

浮点型

Float32 - float

Float64 – double

建议尽可能以整数形式存储数据。例如,将固定精度的数字转换为整数值,如时间用毫秒为单位表示,因为浮点型进行计算时可能引起四舍五入的误差。

3.3 布尔型

没有单独的类型来存储布尔值。可以使用 UInt8 类型,取值限制为 0 或 1。

Decimal 型

有符号的浮点数,可在加、减和乘法运算过程中保持精度。对于除法,最低有效数字会被丢弃(不舍入)。

有三种声明:

➢ Decimal32(s),相当于 Decimal(9-s,s),有效位数为 1~9

Decimal32(5) ===> 整数+小数一共9位,小数部分5位

➢ Decimal64(s),相当于 Decimal(18-s,s),有效位数为 1~18

Decimal64(5) ===> 整数+小数一共18位,小数部分5位

➢ Decimal128(s),相当于 Decimal(38-s,s),有效位数为 1~38 s 标识小数位

使用场景: 一般金额字段、汇率、利率等字段为了保证小数点精度,都使用 Decimal 进行存储。

字符串

1) String

字符串可以任意长度的。它可以包含任意的字节集,包含空字节。

2) FixedString(N)

固定长度 N 的字符串,N 必须是严格的正自然数。当服务端读取长度小于 N 的字符串时候,通过在字符串末尾添加空字节来达到 N 字节长度。 当服务端读取长度大于 N 的字符串时候,将返回错误消息。

与 String 相比,极少会使用 FixedString,因为使用起来不是很方便。使用场景:名称、文字描述、字符型编码。 固定长度的可以保存一些定长的内容,比如一些编码,性别等但是考虑到一定的变化风险,带来收益不够明显,所以定长字符串使用意义有限。

枚举类型

包括 Enum8Enum16 类型。Enum 保存 ‘string’= integer 的对应关系。

Enum8 用 ‘String’= Int8 对描述。

Enum16 用 ‘String’= Int16 对描述。

**1)**用法演示

创建一个带有一个枚举 Enum8(‘hello’ = 1, ‘world’ = 2) 类型的列

CREATE TABLE t_enum

( x Enum8(‘hello’ = 1, ‘world’ = 2)

)

ENGINE = TinyLog;

2)这个 x 列只能存储类型定义中列出的值:'hello’’world’

hadoop102 INSERT INTO t_enum VALUES (‘hello’), (‘world’), (‘hello’);

时间类型

目前 ClickHouse 有三种时间类型

➢ Date 接受年**--**日的字符串比如 ‘2019-12-16’

➢ Datetime 接受年**--日 时::秒的字符串比如 ‘2019-12-16 20:50:10’ ➢ Datetime64 接受年--日 时::.**亚秒的字符串比如‘2019-12-16 20:50:10.66’ 日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。

数组

Array(T):由 T 类型元素组成的数组。

T 可以是任意类型,包含数组类型。 但不推荐使用多维数组,ClickHouse 对多维数组的支持有限。例如,不能在 MergeTree 表中存储多维数组。

(1)创建数组方式 1,使用 array 函数

array(T)

hadoop102 SELECT array(1, 2) AS x, toTypeName(x) ;

三、表引擎

表引擎是 ClickHouse 的一大特色。可以说, 表引擎决定了如何存储表的数据。包括:

➢ 数据的存储方式和位置,写到哪里以及从哪里读取数据。

➢ 支持哪些查询以及如何支持。

➢ 并发数据访问。

➢ 索引的使用(如果存在)。

➢ 是否可以执行多线程请求。

➢ 数据复制参数。

表引擎的使用方式就是必须显式在创建表时定义该表使用的引擎,以及引擎使用的相关参数。

引擎的名称大小写敏感

TinyLog

以列文件的形式保存在磁盘上,不支持索引,没有并发控制。一般保存少量数据的小表,生产环境上作用有限。可以用于平时练习测试用。

如:

create table t_tinylog ( id String, name String) engine=TinyLog;

Memory

内存引擎,数据以未压缩的原始形式直接保存在内存当中,服务器重启数据就会消失。读写操作不会相互阻塞,不支持索引。简单查询下有非常非常高的性能表现(超过 10G/s)。一般用到它的地方不多,除了用来测试,就是在需要非常高的性能,同时数据量又不太大(上限大概 1 亿行)的场景。

MergeTree

ClickHouse 中最强大的表引擎当属 MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎,支持索引和分区.

建表语句example:

create table t_order_mt(     
    id UInt32,     
    sku_id String,     
    total_amount Decimal(16,2),     
    create_time Datetime  ) 
 engine =MergeTree    
 partition by toYYYYMMDD(create_time)
 primary key (id)
 order by (id,sku_id); 

插入数据:

insert into  t_order_mt values 
(101,'sku_001',1000.00,'2020-06-01 12:00:00') , 
(102,'sku_002',2000.00,'2020-06-01 11:00:00'), 
(102,'sku_004',2500.00,'2020-06-01 12:00:00'), 
(102,'sku_002',2000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',12000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',600.00,'2020-06-02 12:00:00'); 

partition by 分区(可选)

1)作用

学过 hive 的应该都不陌生,分区的目的主要是降低扫描的范围,优化查询速度

2)如果不填只会使用一个分区。

3)分区目录

MergeTree 是以列文件+索引文件+表定义文件组成的,但是如果设定了分区那么这些文件就会保存到不同的分区目录中。

4)并行分区后,面对涉及跨分区的查询统计,ClickHouse 会以分区为单位并行处理。

5)数据写入与分区合并任何一个批次的数据写入都会产生一个临时分区,不会纳入任何一个已有的分区。写入后的某个时刻(大概 10-15 分钟后),ClickHouse 会自动执行合并操作(等不及也可以手动通过 optimize 执行),把临时分区的数据,合并到已有分区中。

optimize table 表名 final;
insert into  t_order_mt values 
(101,'sku_001',1000.00,'2020-06-01 12:00:00') , 
(102,'sku_002',2000.00,'2020-06-01 11:00:00'), 
(102,'sku_004',2500.00,'2020-06-01 12:00:00'), 
(102,'sku_002',2000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',12000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',600.00,'2020-06-02 12:00:00'); 

再一次插入以上数据

clickhouse笔记(入门+部分进阶)_第3张图片

此时数据并没有被纳入任何分区

在optimize之后再次查询

clickhouse笔记(入门+部分进阶)_第4张图片

可见已经完成了分区

primary key 主键(可选)

ClickHouse 中的主键,和其他数据库不同,它只提供了数据的一级索引,但是却不是唯一约束。这就意味着是可以存在相同 primary key 的数据的

主键的设定主要依据是查询语句中的 where 条件。

根据条件通过对主键进行某种形式的二分查找,能够定位到对应的 index granularity,避免了全表扫描。

index granularity: 直接翻译的话就是索引粒度,指在稀疏索引中两个相邻索引对应数据的间隔。ClickHouse 中的 MergeTree 默认是 8192。官方不建议修改这个值,除非该列存在大量重复值,比如在一个分区中几万行才有一个不同数据。

稀疏索引:

稀疏索引的好处就是可以用很少的索引数据,定位更多的数据,代价就是只能定位到索引粒度的第一行,然后再进行进行一点扫描。

order by(必选)

order by 设定了分区内的数据按照哪些字段顺序进行有序保存。

order by 是 MergeTree唯一一个必填项,甚至比 primary key 还重要,因为当用户不设置主键的情况,很多处理会依照 order by 的字段进行处理(比如后面会讲的去重和汇总)。

要求:主键必须是 order by 字段的前缀字段。

比如 order by 字段是 (id,sku_id) 那么主键必须是 id 或者(id,sku_id)

副本的表,两台机子的名字要相同,但是分区一定要不同。

二级索引

目前在 ClickHouse 的官网上二级索引的功能在 v20.1.2.4 之前是被标注为实验性的,在

这个版本之后默认是开启的。

1)老版本使用二级索引前需要增加设置

是否允许使用实验性的二级索引(v20.1.2.4 开始,这个参数已被删除,默认开启)

set allow_experimental_data_skipping_indices=1; 

2)创建测试表

  create table t_order_mt2(   
      id UInt32,   
      sku_id String,     
      total_amount  Decimal(16,2),   
      create_time Datetime,    
      INDEX a total_amount TYPE minmax GRANULARITY  5    
)
engine =MergeTree
partition by toYYYYMMDD(create_time)   
primary key (id)
order by (id, sku_id); 

其中 GRANULARITY n

是设定二级索引对于一级索引粒度的粒度

3)插入数据

insert into t_order_mt2 values 
(101,'sku_001',1000.00,'2020-06-01 12:00:00') , 
(102,'sku_002',2000.00,'2020-06-01 11:00:00'), 
(102,'sku_004',2500.00,'2020-06-01 12:00:00'), 
(102,'sku_002',2000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',12000.00,'2020-06-01 13:00:00'), 
(102,'sku_002',600.00,'2020-06-02 12:00:00'); 

4)对比效果那么在使用下面语句进行测试,可以看出二级索引能够为非主键字段的查询发挥作用。

[root@hadoop103 lib]$ clickhouse-client --send_logs_level=trace <<< 'select 

\* from t_order_mt2 where total_amount > toDecimal32(900., 2)'; 

数据 TTL

TTL 即 Time To Live,MergeTree 提供了可以管理数据表或者列的生命周期的功能。

1)列级别 TTL

(1)创建测试表

create table t_order_mt3(   
    id UInt32,   
    sku_id String,   
    total_amount Decimal(16,2) TTL create_time+interval 10 SECOND,   		create_time Datetime  
) 
engine =MergeTree 
partition by toYYYYMMDD(create_time)  
primary key (id)  
order by (id, sku_id); 

(2)插入数据(注意:根据实际时间改变)

insert into t_order_mt3 values 

(106,'sku_001',1000.00,'2020-06-12 22:52:30'), 

(107,'sku_002',2000.00,'2020-06-12 22:52:30'), 

(110,'sku_003',600.00,'2020-06-13 12:00:00'); 

(3)手动合并,查看效果

clickhouse笔记(入门+部分进阶)_第5张图片

1)表级 TTL 下面的这条语句是数据会在 create_time 之后 10 秒丢失

alter table t_order_mt3 MODIFY TTL create_time + INTERVAL 10 SECOND; 

涉及判断的字段必须是 Date 或者 Datetime 类型,推荐使用分区的日期字段。

能够使用的时间周期:

- SECOND

- MINUTE

- HOUR

- DAY

- WEEK

- MONTH

- QUARTER

- YEAR

ReplacingMergeTree

ReplacingMergeTree 是 MergeTree 的一个变种,它存储特性完全继承 MergeTree,只是多了一个去重的功能。 尽管 MergeTree 可以设置主键,但是 primary key 其实没有唯一约束的功能。如果你想处理掉重复的数据,可以借助这个 ReplacingMergeTree。

1)去重时机数据的去重只会在合并的过程中出现。合并会在未知的时间在后台进行,所以你无法预先作出计划。有一些数据可能仍未被处理。

2 去重范围如果表经过了分区,去重只会在分区内部进行去重,不能执行跨分区的去重。

所以 ReplacingMergeTree 能力有限, ReplacingMergeTree 适用于在后台清除重复的数

据以节省空间,但是它不保证没有重复的数据出现。

3)案例演示

(1)创建表

  create table t_order_rmt(    
      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);  

ReplacingMergeTree() 填入的参数为版本字段,重复数据保留版本字段值最大的。如果不填版本字段,默认按照插入顺序保留最后一条。

(2)向表中插入数据

insert into t_order_rmt values 

(101,'sku_001',1000.00,'2020-06-01 12:00:00') , 

(102,'sku_002',2000.00,'2020-06-01 11:00:00'), 

(102,'sku_004',2500.00,'2020-06-01 12:00:00'), 

(102,'sku_002',2000.00,'2020-06-01 13:00:00'), 

(102,'sku_002',12000.00,'2020-06-01 13:00:00'), 

(102,'sku_002',600.00,'2020-06-02 12:00:00'); 

(3)执行查询

optimize table t_order_rmt final;
之后再查询

clickhouse笔记(入门+部分进阶)_第6张图片

4)通过测试得到结论

➢ 实际上是使用 order by 字段作为唯一键

➢ 去重不能跨分区

➢ 只有同一批插入(新版本)或合并分区时才会进行去重 ,并不是一直都会去重

➢ 认定重复的数据保留,版本字段值最大的

➢ 如果版本字段相同则按插入顺序保留最后一笔

SummingMergeTree

对于不查询明细,只关心以维度进行汇总聚合结果的场景。如果只使用普通的MergeTree 的话,无论是存储空间的开销,还是查询时临时聚合的开销都比较大。

ClickHouse 为了这种场景,提供了一种能够“预聚合”的引擎 SummingMergeTree

1)案例演示

(1)创建表

  create table t_order_smt(   
      id UInt32,   
      sku_id String,   
      total_amount Decimal(16,2) ,   
      create_time Datetime    ) 
   engine =SummingMergeTree(total_amount)    
   partition by toYYYYMMDD(create_time)  
   primary key (id)  
   order by (id,sku_id );   

(2)插入数据

insert into t_order_smt values 

(101,'sku_001',1000.00,'2020-06-01 12:00:00'), 

(102,'sku_002',2000.00,'2020-06-01 11:00:00'), 

(102,'sku_004',2500.00,'2020-06-01 12:00:00'), 

(102,'sku_002',2000.00,'2020-06-01 13:00:00'), 

(102,'sku_002',12000.00,'2020-06-01 13:00:00'), 

(102,'sku_002',600.00,'2020-06-02 12:00:00'); 

执行查询:

clickhouse笔记(入门+部分进阶)_第7张图片

合并分区后再查询:

clickhouse笔记(入门+部分进阶)_第8张图片

四、SQL操作

SQL 操作

基本上来说传统关系型数据库(以 MySQL 为例)的 SQL 语句,ClickHouse 基本都支持,这里不会从头讲解 SQL 语法只介绍 ClickHouse 与标准 SQL(MySQL)不一致的地方。

5.1 Insert

基本与标准 SQL(MySQL)基本一致

(1)标准

insert into [table_name] values(),(.) 

(2)从表到表的插入

insert into [table_name] select a,b,c from [table_name_2] 

5.2 Update 和 Delete

ClickHouse 提供了 Delete 和 Update 的能力,这类操作被称为 Mutation 查询,它可以看做 Alter 的一种。

虽然可以实现修改和删除,但是和一般的 OLTP 数据库不一样,Mutation 语句是一种很 “重”的操作,而且不支持事务

只是实现操作

不支持事务!!!!!!!!!!!!!!!!!!!!!!!!!!!

“重”的原因主要是每次修改或者删除都会导致放弃目标数据的原有分区,重建新分区。

所以尽量做批量的变更,不要进行频繁小数据的操作。

(1)删除操作

alter table t_order_smt delete where sku_id =‘sku_001’;

(2)修改操作

alter table t_order_smt update total_amount=toDecimal32(2000.00,2) where id

=102;

由于操作比较“重”,所以 Mutation 语句分两步执行,同步执行的部分其实只是进行新增数据新增分区和并把旧分区打上逻辑上的失效标记。直到触发分区合并的时候,才会删除旧数据释放磁盘空间,一般不会开放这样的功能给用户,由管理员完成。

5.3 查询操作

ClickHouse 基本上与标准 SQL 差别不大

➢ 支持子查询

➢ 支持 CTE(Common Table Expression 公用表表达式 with 子句)

➢ 支持各种 JOIN, 但是 JOIN 操作无法使用缓存,所以即使是两次相同的 JOIN 语句,

ClickHouse 也会视为两条新 SQL

➢ 窗口函数(官方正在测试中…)

➢ 不支持自定义函数

➢ GROUP BY 操作增加了 with rollup\with cube\with total 用来计算小计和总计。

(1)插入数据

hadoop102 :) alter table t_order_mt delete where 1=1; insert into t_order_mt values 

(101,'sku_001',1000.00,'2020-06-01 12:00:00'), 

(101,'sku_002',2000.00,'2020-06-01 12:00:00'), 

(103,'sku_004',2500.00,'2020-06-01 12:00:00'), 

(104,'sku_002',2000.00,'2020-06-01 12:00:00'), (105,'sku_003',600.00,'2020-06-02 12:00:00'), 

(106,'sku_001',1000.00,'2020-06-04 12:00:00'), 

(107,'sku_002',2000.00,'2020-06-04 12:00:00'), 

(108,'sku_004',2500.00,'2020-06-04 12:00:00'), 

(109,'sku_002',2000.00,'2020-06-04 12:00:00'), 

(110,'sku_003',600.00,'2020-06-01 12:00:00'); 

(2)with rollup:从右至左去掉维度进行小计

hadoop103 :) select id , sku_id,sum(total_amount) from t_order_mt group by id,sku_id with rollup; 


clickhouse笔记(入门+部分进阶)_第9张图片

(2)with cube : 从右至左去掉维度进行小计,再从左至右去掉维度进行小计

hadoop103 :) select id , sku_id,sum(total_amount) from t_order_mt group by id,sku_id with cube; 

clickhouse笔记(入门+部分进阶)_第10张图片

hadoop103 :) select id,sku_id,sum(total_amount) from t_order_mt group by id,sku_id with totals;

clickhouse笔记(入门+部分进阶)_第11张图片

alter 操作

同 MySQL 的修改字段基本一致

1)新增字段

alter table tableName add column newcolname String after col1; 

clickhouse笔记(入门+部分进阶)_第12张图片

再查询

clickhouse笔记(入门+部分进阶)_第13张图片

2)修改字段类型

alter table tableName modify column newcolname String; 

clickhouse笔记(入门+部分进阶)_第14张图片

3)删除字段

alter table tableName drop column newcolname; 

clickhouse笔记(入门+部分进阶)_第15张图片

高级

五、Explain查看执行计划

基本语法

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,紧凑打印打,默认开启。注:PLANPIPELINE 还可以进行额外的显示设置,如上参数所示。

实例操作

查看plan

简单查询

hadoop103 :) explain plan select arrayJoin([1,2,3,null,null]);

EXPLAIN
SELECT arrayJoin([1, 2, 3, NULL, NULL])

Query id: 7b29c47d-d55d-4860-b377-b56b3ec56998

┌─explain───────────────────────────────────────────────────────────────────┐
│ Expression ((Projection + Before ORDER BY))                               │
│   SettingQuotaAndLimits (Set limits and quota after reading from storage) │
│     ReadFromStorage (SystemOne)                                           │
└───────────────────────────────────────────────────────────────────────────┘

3 rows in set. Elapsed: 0.012 sec. 

=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

复杂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; 
EXPLAIN
SELECT
    database,
    table,
    count(1) AS cnt
FROM system.parts
WHERE database IN ('datasets', 'system')
GROUP BY
    database,
    table
ORDER BY
    database ASC,
    cnt DESC
LIMIT 2 BY database

Query id: f4580eef-9153-4410-9034-34f758003da6

┌─explain─────────────────────────────────────────────────────────────────────────────────────┐
│ Expression (Projection)                                                                     │
│   LimitBy                                                                                   │
│     Expression (Before LIMIT BY)                                                            │
│       MergingSorted (Merge sorted streams for ORDER BY)                                     │
│         MergeSorting (Merge sorted blocks for ORDER BY)                                     │
│           PartialSorting (Sort each block for ORDER BY)                                     │
│             Expression (Before ORDER BY)                                                    │
│               Aggregating                                                                   │
│                 Expression (Before GROUP BY)                                                │
│                   Filter (WHERE)                                                            │
│                     SettingQuotaAndLimits (Set limits and quota after reading from storage) │
│                       ReadFromStorage (SystemParts)                                         │
└─────────────────────────────────────────────────────────────────────────────────────────────┘

12 rows in set. Elapsed: 0.021 sec. 

=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

打开全部执行计划

EXPLAIN header=1, actions=1,description=1 SELECT number from system.numbers limit 10; 
EXPLAIN header = 1, actions = 1, description = 1
SELECT number
FROM system.numbers
LIMIT 10

Query id: 6906c7e4-b240-4548-810c-529a72919724

┌─explain───────────────────────────────────────────────────────────────────┐
│ Expression ((Projection + Before ORDER BY))                               │
│ Header: number UInt64                                                     │
│ Actions: INPUT :: 0 -> number UInt64 : 0                                  │
│ Positions: 0                                                              │
│   SettingQuotaAndLimits (Set limits and quota after reading from storage) │
│   Header: number UInt64                                                   │
│     Limit (preliminary LIMIT)                                             │
│     Header: number UInt64                                                 │
│     Limit 10                                                              │
│     Offset 0                                                              │
│       ReadFromStorage (SystemNumbers)                                     │
│       Header: number UInt64                                               │
└───────────────────────────────────────────────────────────────────────────┘

12 rows in set. Elapsed: 0.009 sec. 


=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

1)AST 语法树

EXPLAIN AST SELECT number from system.numbers limit 10; 

clickhouse笔记(入门+部分进阶)_第16张图片

2)SYNTAX 语法优化

//先做一次查询 

SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 'atguigu') FROM numbers(10); 

//查看语法优化 

EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 

'atguigu') FROM numbers(10); 


===========结果====================================================================================
 hadoop103 :) EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 
:-] 
:-] 'atguigu') FROM numbers(10); 

EXPLAIN SYNTAX
SELECT if(number = 1, 'hello', if(number = 2, 'world', 'atguigu'))
FROM numbers(10)

Query id: 9dde6b8f-f6ab-456f-bc11-81bb47848619

┌─explain────────────────────────────────────────────────────────────┐
│ SELECT if(number = 1, 'hello', if(number = 2, 'world', 'atguigu')) │
│ FROM numbers(10)                                                   │
└────────────────────────────────────────────────────────────────────┘

2 rows in set. Elapsed: 0.010 sec. 
==================================================================================================

//开启三元运算符优化 

SET optimize_if_chain_to_multiif = 1; 

//再次查看语法优化 

EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 

'atguigu') FROM numbers(10); 

 ========================结果=====================================================================
 hadoop103 :) EXPLAIN SYNTAX SELECT number = 1 ? 'hello' : (number = 2 ? 'world' : 
:-] 
:-] 'atguigu') FROM numbers(10); 

EXPLAIN SYNTAX
SELECT if(number = 1, 'hello', if(number = 2, 'world', 'atguigu'))
FROM numbers(10)

Query id: 01e906dd-13f5-4c5d-8294-07ac7a9209c9

┌─explain────────────────────────────────────────────────────────────┐
│ SELECT if(number = 1, 'hello', if(number = 2, 'world', 'atguigu')) │
│ FROM numbers(10)                                                   │
└────────────────────────────────────────────────────────────────────┘

2 rows in set. Elapsed: 0.004 sec. 
=================================================================================================

//返回优化后的语句 

SELECT multiIf(number = 1, \'hello\', number = 2, \'world\', \'xyz\') FROM numbers(10) 

4)查看 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; 


结果:

hadoop103 :) EXPLAIN PIPELINE header=1,graph=1 SELECT sum(number) FROM numbers_mt(10000) GROUP BY number%20; 

EXPLAIN PIPELINE header = 1, graph = 1
SELECT sum(number)
FROM numbers_mt(10000)
GROUP BY number % 20

Query id: 50a05a45-48ed-42e8-b7a8-3bdd91a181e3

┌─explain─────────────────────────────────────┐
│ digraph                                     │
│ {                                           │
│   rankdir="LR";                             │
│   { node [shape = box]                      │
│         n2 [label="Limit"];                 │
│         n1 [label="Numbers"];               │
│     subgraph cluster_0 {                    │
│       label ="Expression";                  │
│       style=filled;                         │
│       color=lightgrey;                      │
│       node [style=filled,color=white];      │
│       { rank = same;                        │
│         n3 [label="ExpressionTransform"];   │
│       }                                     │
│     }                                       │
│     subgraph cluster_1 {                    │
│       label ="Expression";                  │
│       style=filled;                         │
│       color=lightgrey;                      │
│       node [style=filled,color=white];      │
│       { rank = same;                        │
│         n5 [label="ExpressionTransform"];   │
│       }                                     │
│     }                                       │
│     subgraph cluster_2 {                    │
│       label ="Aggregating";                 │
│       style=filled;                         │
│       color=lightgrey;                      │
│       node [style=filled,color=white];      │
│       { rank = same;                        │
│         n4 [label="AggregatingTransform"];  │
│       }                                     │
│     }                                       │
│   }                                         │
│   n2 -> n3 [label="                         │
│ number UInt64 UInt64(size = 0)"];           │
│   n1 -> n2 [label="                         │
│ number UInt64 UInt64(size = 0)"];           │
│   n3 -> n4 [label="                         │
│ number UInt64 UInt64(size = 0)              │
│ modulo(number, 20) UInt8 UInt8(size = 0)"]; │
│   n4 -> n5 [label="                         │
│ modulo(number, 20) UInt8 UInt8(size = 0)    │
│ sum(number) UInt64 UInt64(size = 0)"];      │
│ }                                           │
└─────────────────────────────────────────────┘

45 rows in set. Elapsed: 0.012 sec. 

你可能感兴趣的:(zookeeper,mysql,database,big,data,大数据)