clickhouse 常用DDL操作(二)
常用DDL操作
在集群操作下,必要要加上 **on CLUSTER ‘all-replicated’**,clickhouse中对更新数据很有限,尽量不要操作更新数据。
建表语句
1 | CREATE TABLE 库名.表名 on CLUSTER 'all-replicated'(1) |
(1) on CLUSTER ‘all-replicated’:表示在集群下的所有节点创建
(2) minmax: 二级索引中的范围过索引,常见的Set、Bloom Filter Types、minmax等
(3) GRANULARITY:每个索引块由颗粒(granule)组成,上述 GRANULARITY为4,索引的数据=index_granularity * 4 = 4*8192 = 32768
(4) ENGINE:表引擎,上面使用的ReplicatedMergeTree是副本合并树(MergeTree)引擎,与普通的MergeTree人区别多了一个副本(备份)功能,常用的表引擎有MergeTree、TinyLog、Memory等
(5) {shard}:分片通配符,集群会获取有多少个主分区节点(适合大数据量,至少以亿为单位数据),并在zookeeper上创建对应的表元素文件同步集群的表元素
(6) {replica}:副本通配符集群会获取有主分区下有多少副本节点,并在zookeeper上创建对应的表元素文件同步集群的表元素,如果其中一个zookeeper中表的元素与实表的元素对不上,会产生锁表(只读),以防止副本之前的数据混乱。
(7) toYYYYMMDD():格式化日期,例如toYYYYMMDD(‘2023-08-03 06:55:27’) 得到 2023-08-03
(8) PARTITION BY:分区,一般用天分区,一同一张表中分区不宜过多,难以维护,以一张表中1亿条数据为例,建议20-30个分区最优。
(9) PRIMARY KEY:主键,优先选择高基数的元数据,必须遵从最左原则,也就是基数越高应该在最左边。主键索引采用的稀疏主索引,使用二分查询法来定位数据所在快
(10) ORDER BY:排序键,排序字段必须包含主键字段,例如上述主健是id,所以排序字段为:id,create_time
(11) index_granularity = 8192:显式设置为其默认值8192。这意味着对于每一组8192行,主索引将有一个索引条目
(15) index_granularity_bytes=0:设置为0表示禁止自适应索引粒度
删除表数据
DROP
删除表结构和表中数据
1 | #如果集群一定要带 on CLUSTER 'all-replicated' |
TRUNCATE
删除表中的数据
1 | #如果集群一定要带 on CLUSTER 'all-replicated' |
表优化操作
二级索引(调数索引)
二级索引根据分区、组、快中的记录的最大值与最小值,最好用于dataTime类型的高基数的字段或者,可以有效加速查询速度。
(1) 建表时创建二级索引
在创建表元素中加下列语句,参考创建表语句
1 | INDEX 二级索引名称 元数据 TYPE minmax(2) GRANULARITY(3) 4, |
(2) 对已有的表增加二级索引
1 | alter table 表名 [on CLUSTER 'all-replicated'] add index 索引名(表元素) type 类型 granularity 大小; |
对已存在的表新增二级索引,需要手动物化索引
1 | alter tabel 表名 [on CLUSTER 'all-replicated'] MATERIALIZE INDEX 索引名称 |
(3) 删除二级索引
1 | alter table 表名 [on CLUSTER 'all-replicated'] DROP index 索引名称; |
优化表
由于clickhouse的机制,当数据插入后不会直接合并到已有分区中,会创建已知已知临时分区,clickhouse会在后台某个时刻自动合并和处理数据。
显示声明clickhouse优化表中数据,需要使用 optimize
1 | optimize table 表名 [on CLUSTER 'all-replicated'] |
*注意:应当在空闭时使用上述语句,因为该操作会进行大量的重构,可能会影响业务查询。
系统表中的清理
系统表中会记录大量操作日志,当占用大量存储空间时,可以适当进行删除日志,常用系统日志有如下:
1 | 1. system.metric_log |
不建议直接删除数据,可以采用ddl方式删除表的分区,达到删除数据,避免删除行数据时,索引或者存储文件发生大量变更,clickhouse对数据的更新操作非常困难,因此不建议删除行或者更新行数据
以system.trace_log为例
(1) 查询trace_log表的分区
1 | select * from system.parts where database='system' and table='trace_log' |
(2) 删除指定的分区
1 | alter table system.trace_log on CLUSTER 'all-replicated' drop partition '分区名称' |
分析操作
explain
查询sql执行计划
1 | 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,紧凑打印打,默认开启
打印当前sql执行的日志
当大量日志记录时,难以找到执行sql执行计划时,可以使用下列命令打印sql语句执行日志信息。
1 | clickhouse-client -h localhost --send_logs_level=trace <<< " sql语句 " > /dev/null |
1 | #执行时出现上面异常错误,说明clickhouse-client 登录有密码, 请加上--password 密码 |
主要日志解析:
1.where过滤条件,注意where中的start_bjtime字段不在这个位置,分区中记录的start_bjtime列min和max值,可以提前过滤大部分分区,推荐使用时间类型的字段
2.MinMax inde:表示范围索引,where中有分区字段才能使用
3.where条件命中的分区,
4.命中分区中的那些数据marks(数据组),clickhouse采用十分查询,索引存在左右两份数据,左边0命中,右边1命中
5.二级索引生效提示,0/1granules表示数据块只有1个,跳过0个分区. Select….表示命中1个分区,1个主键索引,1个数据组索引,1个块
6.prewhere表示预读数据
7.(7)表示共读取的一个分区,8192行(索引下颗粒度,创建表时指定),Read 1200 :表示完成命中条件有1200行数据,大小为92.58kb 执行时间:0.00311s=3.11ms,速度:每秒读取385852行,每秒读取29.01M