首页 > 其他分享 >7.ClickHouse系列之查询优化(一)

7.ClickHouse系列之查询优化(一)

时间:2022-10-21 21:48:04浏览次数:76  
标签:EXPLAIN UserID 查询 v1 ClickHouse SYNTAX 优化 SELECT

1. Explain查询计划查看

// 查看执行计划,默认值
EXPLAIN PLAN SELECT arrayJoin([6,6,7])
// AST语法树查看
EXPLAIN AST SELECT numbers FROM system.numbers LIMIT 10;
// 用于优化语法
EXPLAIN SYNTAX SELECT arrayJoin([6,6,7])
// 查看PIPELINE计划
EXPLAIN PIPELINE SELECT arrayJoin([6,6,7])

2. 建表优化

2.1 数据类型
  • 时间字段类型:建表时能用数值型或日期时间表示的字段就不要用字符串。虽然ClickHouse底层将DateTime存储为时间戳Long类型,但不建议存储Long类型,因为DateTime不需要经过函数转换处理,执行效率高,可读性好
  • 空值存储类型:官方指出Nullable类型几乎总是会拖累性能。因为存储Nullable列时需要创建一个额外的文件来存储NULL的标识(具体var/lib/clickhouse/data/table/column.null.bin),并且Nullable列无法被索引。应直接使用字段默认值表示空,或者自行指定一个在业务中无意义的值
2.2 分区与索引

分区粒度根据根据业务特点决定,不宜过粗过细。一般选择按天分区。必须指定索引列,ClickHouse中索引列即排序列,通过order by指定。组合索引需满足查询频率大在前。基数特别大的列不适宜做索引列

3 ClickHouse内部语法优化规则

3.1 Count优化

如果使用的是count()或count(*),只要没指定具体字段,且没有where条件,则会直接使用system.tables的total_rows:

SELECT COUNT() FROM datasets.hits_vl;
3.2 子查询\ORDER BY\LIMIT BY\USING KEY重复字段会自动消除
3.3 谓词下推
EXPLAIN SYNTAX SELECT UserID FROM hits_v1 GROUP BY UserID Having UserID='111';
会被自动优化为
EXPLAIN SYNTAX SELECT UserID FROM hits_v1 WHERE UserID='111' GROUP BY UserID;
3.4 聚合函数外推
EXPLAIN SYNTAX SELECT SUM(UserID*2) FROM visits_v1;
会被自动优化为
SELECT SUM(UserID) * 2 FROM visits_v1;
3.5 聚合函数消除
EXPLAIN SYNTAX SELECT SUM(UserID*2),max(VisitID), max(UserID) FROM visits_v1 GROUP BY UserID;
会被自动优化为
EXPLAIN SYNTAX SELECT SUM(UserID) * 2, max(VisitID), UserID FROM visits_v1 GROUP BY UserID;
3.6 三元运算优化
EXPLAIN SYNTAX SELECT number=1?'hello':(number=2?'world':'china') FROM numbers(10) SETTINGS optimize_if_chain_to_multiif=1;
返回优化后的语句:
─explain───────────────────────────────────────────────────────────┐
│ SELECT multiIf(number = 1, 'hello', number = 2, 'world', 'china') │
│ FROM numbers(10)                                                  │
│ SETTINGS optimize_if_chain_to_multiif = 1                         │
└───────────────────────────────────────────────────────────────────┘

4 单表查询优化

4.1 prewhere代替where

prewhere和where语句的作用相同,用来过滤数据。不同之处在于prewhere只支持*MergeTree族系列引擎的表,首先会读取指定的列数据,来判断数据过滤,等待数据过滤之后在读取select声明的列字段来补全其余属性。默认情况下,where条件会自动优化成prewhere。

4.2 数据采样

通过采样运算可极大提升数据分析的性能

SELECT Title, count(*) AS PageViews FROM hits_v1 SAMPLE 0.1 WHERE CounterID=57 GROUP BY Title;
4.3 列裁剪与分区裁剪

列裁剪即指定所需要的列,而非全量*,分区裁剪就是只读取需要的分区,在过滤条件中指定

4.4 order by结合where limit

千万以上数据集进行order by查询时需要搭配where条件和limit语句一起使用

4.5 避免构建虚拟列

不要在结果集上构建虚拟列,非常消耗资源降低性能。

// 反例
SELECT Income, Age, Income/Age AS Ia FROM datasets.hits_v1;
4.6 uniqCombined替代distinct

性能可提升10倍以上,uniqCombined底层采用类似HyperLogLog算法实现。不建议在千万级数据上执行distinct去重查询,改为近似去重uniqCombined。

4.7 考虑使用物化视图

ClickHouse的物化视图是一种查询结果的持久化。物化视图不会随着基础表的变换而变化,被称为'快照',
如下表而言,当发布日期大于10月1日,会在物化视图的存储表.inner_id.xxxx中插入数据,而当清空基础表house时,.inner_id.xxxx中的数据并不会丢失。

// 创建物化视图
CREATE MATERIALIZED VIEW study.house_new_mv ENGINE ReplacingMergeTree PARTITION BY toYYYYMMDD(publish_date) ORDER BY(id, city, region, name)
AS SELECT id, city, region, name, publish_date FROM study.house WHERE publish_date > toDate('2022-10-01');
// 插入数据
INSERT INTO study.house VALUES (2, '上海', '静安', '彭一小区', 70000, toDateTime('2022-05-06'));
INSERT INTO study.house VALUES (2, '上海', '静安', '彭一小区', 70000, toDateTime('2022-10-06'));
TRUNCATE TABLE study.house;
SELECT * FROM study.house_new_mv;

3
欢迎关注公众号算法小生沈健的技术博客

标签:EXPLAIN,UserID,查询,v1,ClickHouse,SYNTAX,优化,SELECT
From: https://www.cnblogs.com/shenjian-online/p/16814843.html

相关文章

  • 8.ClickHouse系列之查询优化(二)
    本文介绍多表关联查询优化方式1.用IN代替JOIN当多表查询时,查询的数据仅从一张表出时,可考虑用IN操作而不是JOINSELECTa.*FROMhits_v1aWHEREa.CounterIDin(SELEC......
  • 1.ClickHouse系列之Docker本地部署
    本文介绍docker-compose方式部署clickhouse数据库编写docker-compose.yml文件:version:'3'services:elasticsearch:image:clickhouse/clickhouse-server......
  • 2.ClickHouse系列之特点介绍
    1.列式存储采用列式存储时,数据在磁盘上的组织结构为:123张三李四王五182025好处:对于列的聚合、计数、求和等统计操作由于列式存储由于列数据类型相同,更容易......
  • 3.ClickHouse系列之SQL操作
    首先我们建表,表引擎我们后续文章在详细介绍,我们首先了解下基本SQL语法CREATEDATABASEstudy;CREATETABLEstudy.customer(idUInt8,cityString,name......
  • 4.ClickHouse系列之数据类型与表引擎介绍
    上篇文章已经创建过表及熟悉了基本语法,本文介绍CK的数据类型以及表引擎的一些分类与作用1.数据类型类型整型Int8Int16Int32Int64浮点型Float32Flo......
  • 基于链式前向星的堆优化dijsktra | 模板
    关于SPFA,ta死了基于链式前向星的堆优化\(dijsktra\):复杂度\(O(mlogn)\),要求非负权。#include<iostream>#include<cstdio>#include<cstring>#include<queue>#inc......
  • ClickHouse(二)优化
    ClickHouse优化执行计划    AST(语法树)、SYNTAX(优化后的SQL语句)、PIPELINE(查看PIPELINE计划,可看线程数)建表优化    数据类型优化:1.限定好数据类型  2.......
  • Starrocks坏盘后数据无法查询恢复的步骤
    1.先进入/opt/starRocks/be/conf把坏盘从数据盘中删除2.停止服务停止be服务bin/stop_be.sh3.启动服务 bin/start_be.sh--daemon因为是三副本,所以数据是不会丢失......
  • .net core -利用 BsonDocumentProjectionDefinition 和Lookup 进行 join 关联 MongoDB
    前序   前段时间由于项目需要用到MongoDB,但是MongoDB不建议Collectionjoin 查询,网上很多例子查询都是基于linq进行关联查询。但是在stackoverflow找到一个例子,程......
  • es通过时间聚合查询一周中每天的数据平均值
    场景回顾:设备上传的数据保存在es中,大屏模块要统计本周的数据折线图(一个设备三分总上传一次,所以拟定每天聚合求个平均值)kibana查询请求GETxxxx_2022-10/_search{"s......