clickhouse mergeTree表引擎解析

参照

https://clickhouse.com/docs/zh/engines/table-engines/mergetree-family/mergetree

https://clickhouse.com/docs/en/optimize/skipping-indexes

Clickhouse中最强大的表引擎当属MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎。

MergeTree 系列的引擎被设计用于将极大量的数据插入到一张表当中。数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合并。相比在插入时不断修改(重写)已存储的数据,这种策略会高效很多。

主要特点

  • 存储的数据按主键排序,因此可以创建一个小型的稀疏索引来加快数据检索。
  • 可以指定分区键进行分区,查询中指定来分区键时Clickhouse会自动截取分区数据,提高查询性能。
  • 支持数据副本
  • 支持数据采样

建表语句

建表语句语法如下

子句解析

  • ENGINE  ——  引擎名和参数。ENGINE = MergeTree(),MergeTree引擎没有参数。
  • ORDER BY  ——  排序键。可以是一组列的元组或任意的表达式,例如ORDER BY(CounterID, EventDate)。如果没有使用PRIMARY KEY显式指定主键,ClickHouse会使用排序键作为主键。如果不需要排序,可以使用ORDER BY tuple()。
  • PARTITION BY  ——  分区键,可选项。大多数情况下,不需要使用分区键。即使需要,也不需要使用比月更细粒度的分区键。分区不会加快查询(这与ORDER BY表达式不同)。永远也别使用过细粒度的分区键。不要使用客户端指定分区标识符或分区字段名称来对数据进行分区(而是将分区字段标识或名称作为 ORDER BY 表达式的第一列来指定分区)。要按月分区,可以使用表达式 toYYYYMM(date_column) ,这里的 date_column 是一个 Date 类型的列。分区名的格式会是 "YYYYMM" 。
  • PRIMARY KEY  ——  如果要选择与排序键不同的主键,在这里指定,可选项。默认情况下主键跟排序键相同。因此,大部分情况下不需要再专门指定一个PRIMARY KEY子句。
  • SAMPLE BY  ——  用于抽样的表达式,可选项。如果要用抽样表达式,主键中必须包含这个表达式。例如SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID)) 。
  • TTL  ——  指定行存储的持续时间并定义数据片段在硬盘和卷上的移动逻辑的规则列表,可选项。表达式中必须至少有一个Date或DateTime类型的列,比如: TTL date + INTERVAL 1 DAY。
  • SETTINGS  ——  控制MergeTree行为的额外参数,可选项。

表数据存储

表由按主键排序的数据片段(DATA PART)组成。

当数据被插入到表中时,会创建多个数据片段并按主键的字典序排序。例如,主键是(CounterID, Date)时,片段中数据首先按CounterID排序,具有相同CounterID的部分按Date排序。

不同分区的数据会被分成不同的片段,ClickHouse在后台合并数据片段以便高效存储。不同分区的数据片段不会进行合并。合并机制并不保证具有相同主键的行全都合并到一个数据片段中。

数据片段可以以 Wide 或 Compact 格式存储。在 Wide 格式下,每一列都会在文件系统中存储为单独的文件,在 Compact 格式下所有列都存储在一个文件中。Compact 格式可以提高插入量少插入频率频繁时的性能。

主键和索引

以(CounterID, Date)为主键。排序好的索引效果如下图所示:

如果指定查询如下:

ClickHouse不要求主键唯一,所以可以插入多条具有相同主键的行。

索引存储的就是标记、标记号,上述示意图就是set类型索引。

主键的选择

主键中列的数量并没有明确的限制。依据数据结构,您可以在主键包含多些或少些列。这样可以:

  • 改善索引的性能
  • 如果当前主键是(a, b),在下列情况下添加另一个c列会提升性能:
  • 查询会使用c列作为条件
  • 很长的数据范围(index_granularity的数倍)里(a,b)都是相同的值,并且这样的情况很普遍。换言之,就是加入另一列后,可以让查询略过很长的数据范围。
  • 改善数据压缩。clickhouse以主键排序片段数据,所以,数据的一致性越高,压缩越好。

长的主键会对插入性能和内存消耗有负面影响,但主键中额外的列并不影响SELECT查询的性能。

可以使用ORDER BY tuple()语法创建没有主键的表。在这种情况下ClickHouse根据数据插入的顺序存储。如果在使用INSERT 。。。SELECT时希望保持数据的排序,请重置max_insert_threads=1。

想要根据初始顺序进行数据查询,使用单线程查询

选择与排序键不同的主键

Clickhouse可以做到指定一个跟排序键不一样的主键,此时排序键用于在数据片段中进行排序,主键用于在索引文件中进行标记的写入。这种情况下,主键表达式元祖必须是排序键表达式元祖的前缀(即主键为(a,b)),排序列必须为(a,b,**))。

当使用 SummingMergeTree 和 AggregatingMergeTree 引擎时,这个特性非常有用。通常在使用这类引擎时,表里的列分两种:维度 和 度量 。典型的查询会通过任意的 GROUP BY 对度量列进行聚合并通过维度列进行过滤。由于 SummingMergeTree 和 AggregatingMergeTree 会对排序键相同的行进行聚合,所以把所有的维度放进排序键是很自然的做法。但这将导致排序键中包含大量的列,并且排序键会伴随着新添加的维度不断的更新。

在这种情况下合理的做法是,只保留少量的列在主键当中用于提升扫描效率,将维度列添加到排序键中。

对排序键进行 ALTER 是轻量级的操作,因为当一个新列同时被加入到表里和排序键里时,已存在的数据片段并不需要修改。由于旧的排序键是新排序键的前缀,并且新添加的列中没有数据,因此在表修改时的数据对于新旧的排序键来说都是有序的。

索引和分区在查询中的应用

对于SELECT查询,Clickhouse分析是否可以使用索引。如果WHERE/PREWHERE子句具有下面这些表达式(作为完整WHERE条件的一部分或全部)则可以使用索引:进行相等/不相等的比较;对主键列或分区列进行IN运算、有固定前缀的LIKE运算(如name like 'test%')、函数运算(部分函数适用),以及对上述表达式进行逻辑运算。

因此,在索引键的一个或多个区间上快速地执行查询是可能的。下面例子中,指定标签;指定标签和日期范围;指定标签和日期;指定多个标签和日期范围等执行查询,都会非常快。

当引擎配置如下时:

    ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate) SETTINGS index_granularity=8192

以下查询

SELECT count() FROM table WHERE EventDate = toDate(now()) AND CounterID = 34

SELECT count() FROM table WHERE EventDate = toDate(now()) AND (CounterID = 34 OR CounterID = 42)

SELECT count() FROM table WHERE ((EventDate >= toDate('2014-01-01') AND EventDate <= toDate('2014-01-31')) OR EventDate = toDate('2014-05-01')) AND CounterID IN (101500, 731962, 160656) AND (CounterID = 101500 OR EventDate != toDate('2014-05-01'))

ClickHouse会依据主键索引剪掉不符合的数据,依据按月分区的分区键剪掉那些不包含符合数据的分区。

下面这个例子中,不会使用索引。

SELECT count() FROM table WHERE CounterID = 34 OR URL LIKE '%upyachka%'

要检查 ClickHouse 执行一个查询时能否使用索引,可设置如下两个 参数force_index_by_date 和 force_primary_key 。

使用按月分区的分区列允许只读取包含适当日期区间的数据块,这种情况下,数据块会包含很多天(最多整月)的数据。在块中,数据按主键排序,主键第一列可能不包含日期。因此,仅使用日期而没有用主键字段作为条件的查询将会导致需要读取超过这个指定日期以外的数据。

跳数索引

此索引在CREATE语句的列部分里定义,如下所示

INDEX index_name expr TYPE type(...) GRANULARITY granularity_value

*MergeTree 系列的表可以指定跳数索引。 跳数索引是指数据片段按照粒度(建表时指定的index_granularity)分割成小块后,将上述SQL的granularity_value数量的小块组合成一个大的块,对这些大块写入索引信息,这样有助于使用where筛选时跳过大量不必要的数据,减少SELECT需要读取的数据量。

示例

CREATE TABLE table_name

(

    u64 UInt64,

    i32 Int32,

    s String,

    ...

    INDEX a (u64 * i32, s) TYPE minmax GRANULARITY 3,

    INDEX b (u64 * length(s)) TYPE set(1000) GRANULARITY 4

) ENGINE = MergeTree()

...

示例中的索引能让ClickHouse执行下面这些查询时减少读取的数据量。

SELECT count() FROM table WHERE s < 'z'

SELECT count() FROM table WHERE u64 * i32 == 10 AND u64 * length(s) >= 1234

可用的索引类型

  • minmax  存储指定表达式的极值(如果表达式tuple,则存储tuple中每个元素的极值),这些信息用于跳过数据块,类似主键。
  • set(max_rows)  存储指定表达式的不重复值(不超过max_rows个,max_rows=0 则表示不限制)。这些信息可用于检查数据块是否满足WHERE条件。
  • ngrambf_v1(n,size_of_bloom_filter_in_bytes,number_of_hash_functions,random_seed)存储一个包含数据块中所有 n元短语(ngram)的 布隆过滤器 。只可用在字符串上。 可用于优化 equals , like 和 in 表达式的性能。

函数支持

WHERE子句中的条件可以包含对某列数据进行运算的函数表达式,如果列是索引的一部分,ClickHouse会在执行函数时尝试使用索引。不同的函数对索引的支持是不同的。

set索引对所有函数生效,其他索引对函数的生效情况见下表

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

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

相关文章

通过红黑树封装 map 和 set 容器

一、红黑树的迭代器 红黑树的遍历默认为中序遍历 —— key 从小到大&#xff0c;因此 begin() 应该获取到红黑树的最左节点 —— 最小&#xff0c;end() 获取到红黑树最右节点的下一个位置&#xff0c; operator() 也应保证红黑树的遍历为中序的状态。 首先对红黑树节点进行改造…

骨传导耳机怎么选?五款高分热销榜骨传导耳机单品推荐!

骨传导耳机哪个牌子好&#xff1f;作为资深数码博主&#xff0c;许多朋友都希望我能够分享一些关于骨传导耳机的选购技巧。随着时间的发展&#xff0c;市面上的骨传导耳机种类日渐繁多&#xff0c;其中品牌的专业实力参差不齐&#xff0c;产品质量也千差万别。一些黑心商家为了…

家装空间3D建模素材:打造理想家园的必备工具

在家装过程中&#xff0c;设计师和业主往往需要通过3D建模技术来实现对空间的精确规划和设计。3D建模素材作为这一领域的基础元素&#xff0c;为设计师提供了丰富的想象空间&#xff0c;帮助他们更好地呈现业主的期望和需求。 这些3D建模素材可以涵盖各种家装元素&#xff0c;如…

roofline model加速模型部署最后一公里

文章目录 模型部署教程来啦:)什么是Roofline Model&#xff1f;算法模型相关指标计算量计算峰值参数量访存量带宽计算密度kernel size对计算密度的影响output size对计算密度的影响channel size对计算密度的影响group convolution对计算密度的影响tensor reshape对计算密度的影…

linux 性能监控命令之dstat

1. dstat 系统默认为安装&#xff0c;直接安装阿里源后&#xff0c;yum install -y dstat安装即可&#xff0c;该命令整合了 vmstat &#xff0c; iostat 和 ifstat&#xff0c;我们先看下效果&#xff1a; 我们先看看具体参数&#xff1a; [rootk8s-master ~]# dstat --help …

Python AI库pandas读写数据库的应用操作——以sqlite3为例

Python AI库pandas读写数据库的应用操作——以sqlite3为例 本文默认读者具备以下技能&#xff1a; 熟悉python基础知识&#xff0c;vscode或其它编辑工具 已阅读Pandas基础操作文章,了解pandas常见操作 具备自主扩展学习能力 在数据分析和人工智能领域&#xff0c;pandas库和s…

怎么批量修改图片的大小?分享几个方法

现在不管是在自媒体还是在各种社交媒体平台中&#xff0c;我们都会用到大量的图片&#xff0c;有时候会发现图片尺寸过大&#xff0c;对上传或者储存带来了不小的困难&#xff0c;在这种情况下&#xff0c;调整图片尺寸显得格外重要&#xff0c;通过修改图片尺寸&#xff0c;我…

# 从浅入深 学习 SpringCloud 微服务架构(八)Sentinel(2)

从浅入深 学习 SpringCloud 微服务架构&#xff08;八&#xff09;Sentinel&#xff08;2&#xff09; 一、sentinel&#xff1a;通用资源保护 1、Rest 实现熔断 Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护, 在构造 RestTemplate…

[华为OD]C卷 BFS 亲子游戏 200

题目&#xff1a; 宝宝和妈妈参加亲子游戏&#xff0c;在一个二维矩阵&#xff08;N*N&#xff09;的格子地图上&#xff0c;宝宝和妈妈抽签决定各自 的位置&#xff0c;地图上每个格子有不同的Q糖果数量&#xff0c;部分格子有障碍物。 游戏规则Q是妈妈必须在最短的时间&a…

预兼容性EMC测试基础

介绍――预兼容性EMC测试的重要意义 在产品开发过程中&#xff0c;您最想做的是对器件进行测试&#xff0c;验证其是否正常工作。所有电子器件都必须在经过认证的内部测试中心内成功通过电磁兼容性EMI测试。通过 EMI测试即表明您的器件的 EMI 发射性能达到允许水平&#xff0c;…

Hive UDTF之explode函数、Lateral View侧视图

Hive UDTF之explode函数 Hive 中的 explode() 函数是一种用于处理数组类型数据的 User-Defined Table-Generating Function (UDTF)。它将数组拆分成多行&#xff0c;每个数组元素对应生成的一行数据。这在处理嵌套数据结构时非常有用&#xff0c;例如处理 JSON 格式的数据。 …

详细介绍一下PointPillars算法的网络结构

PointPillars是一种用于3D目标检测的算法&#xff0c;它主要使用了点云数据和深度学习模型。 PointPillars算法的网络结构主要可以分为三个主要阶段&#xff1a; Pillar Feature Net&#xff08;点云特征处理网络&#xff09;&#xff1a;此阶段的主要任务是将输入的点云数据转…

怎样单独提取PDF文件中的一个或几个文件?分割PDF文件的方法

在现代数字化时代&#xff0c;PDF文件已成为我们日常生活和工作中不可或缺的一部分。 一&#xff0c;首先了解什么是PDF&#xff1f; PDF&#xff0c;即“Portable Document Format”&#xff0c;意为“便携式文档格式”&#xff0c;由Adobe Systems开发。由于其跨平台、不易…

探秘Appium:Capability 进阶技巧揭秘!

简介 Appium 的除了基础的 Capability 设置&#xff0c;还提供了许多辅助配置项&#xff0c;用于优化自动化测试。这些配置项旨在执行基础配置之外的附加操作。例如&#xff1a;指定设备别名、设备 ID 或是设置超时时间等&#xff0c;虽然这些不是必需的选项&#xff0c;但是为…

【Linux系统编程】第十五弹---调试器gdb使用

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、背景 2、安装gdb 3、gdb的使用 总结 1、背景 前面我们学习了文件编辑器&#xff0c;项目自动化构建工具&#xff0c;以及g…

目标检测算法YOLOv6简介

YOLOv6由Chuyi Li等人于2022年提出&#xff0c;论文名为&#xff1a;《YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications》&#xff0c;论文见&#xff1a;https://arxiv.org/pdf/2209.02976 &#xff0c;项目网页&#xff1a;https://github.c…

Python程序设计 函数(三)

练习十一 函数 第1关&#xff1a; 一元二次方程的根 定义一个函数qg&#xff0c;输入一元二次方程的系数a,b,c 当判别式大于0&#xff0c;返回1和两个根 当判别式等于0&#xff0c;返回0和两个根 当判别式小于0&#xff0c;访问-1和两个根 在主程序中&#xff0c;根据函数返回…

大模型微调之 在亚马逊AWS上实战LlaMA案例(三)

大模型微调之 在亚马逊AWS上实战LlaMA案例&#xff08;三&#xff09; 使用 QLoRA 增强语言模型&#xff1a;Amazon SageMaker 上 LLaMA 2 的高效微调 语言模型在自然语言处理任务中发挥着关键作用&#xff0c;但训练和微调大型模型可能会占用大量内存且耗时。在本文中&…

STM32 各外设GPIO配置

高级定时器TIM1/TIM8 通用定时器TIM2/3/4/5 USART SPI I2S I2C接口 BxCAN SDIO ADC/DAC 其它I/O功能

【数据库原理及应用】期末复习汇总高校期末真题试卷08

试卷 一、选择题(每题 2 分&#xff0c;共 30 分)    1. ___ ____是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 2. 数据库类型是按照 来划分…