【ClickHouse内核】对于分区、索引、标记和压缩数据的协同工作

2023-11-16

目录

概述

写入过程

生成分区目录

生成索引

生成标记和数据压缩文件

各个底层物理文件生成的过程

查询过程

借助索引文件降低扫描范围

借助标记文件降低解压数据的大小

数据标记与压缩数据块的对应关系

多个数据标记对应一个压缩数据块

一个数据标记对应一个压缩数据块

一个数据标记对应多个压缩数据块

结论


概述

分区、索引、标记和压缩数据,这些组件配合在一起给ClickHouse数据库带来非常高效的查询性能。前面的文章也单独介绍了这几个组件。接下来,就分别从写入过程、查询过程,以及数据标记与压缩数据块的三种对应关系的角度展开介绍。

 

写入过程

生成分区目录

数据写入的第一步是生成分区目录,伴随着每一批数据的写入,都会生成一个新的分区目录。在后续的某一时刻,属于相同分区的目录会依照规则合并到一起。

 

生成索引

按照index_granularity索引粒度,会分别生成primary.idx主键索引(如果声明了二级索引,还会创建二级索引文件)。

 

生成标记和数据压缩文件

按照index_granularity索引粒度,分别生成每一个列字段的.mrk数据标记和.bin压缩数据文件。

 

各个底层物理文件生成的过程

下图所示是一张MergeTree表在写入数据时,它的分区目录、索引、标记和压缩数据的生成过程。

从分区目录201403_1_34_3能够得知,该分区数据共分34次写入,期间发生过3次合并。在数据写入的过程中,依据index_granularity的粒度,依次为每个区间的数据生成索引、标记和压缩数据块。其中,索引和标记区间是对齐的,而标记与压缩块则根据区间数据大小的不同,会生成多对一、一对一和一对多三种关系。

 

查询过程

借助索引文件降低扫描范围

数据查询的本质,可以看作一个不断减小数据范围的过程。在最理想的情况下,MergeTree首先可以依次借助分区索引、主键索引和二级索引,将数据扫描范围缩至最小。

 

借助标记文件降低解压数据的大小

然后再借助数据标记,将需要解压数据块与计算的数据范围缩至最小。以下图所示为例,它示意了在最优的情况下,经过层层过滤,最终获取最小范围数据的过程。

 

如果一条查询语句没有指定任何WHERE条件,或是指定了WHERE条件,但条件没有匹配到任何索引(分区索引、主键索引和二级索引),那么MergeTree就不能预先减小数据范围。在后续进行数据查询时,它会扫描所有分区目录,以及目录内索引段的最大区间。虽然不能减少数据范围,但是MergeTree仍然能够借助数据标记,以多线程的形式同时读取多个压缩数据块,以提升性能。

 

数据标记与压缩数据块的对应关系

由于压缩数据块的划分,与一个间隔(index_granularity)内的数据大小相关,每个压缩数据块的体积都被严格控制在64KB~1MB。而一个间隔(index_granularity)的数据,又只会产生一行数据标记。那么根据一个间隔内数据的实际字节大小,数据标记和压缩数据块之间会产生三种不同的对应关系。接下来使用具体示例做进一步说明,对于示例数据,我们使用的是官方测试数据集中的测试表hits_v1,其中index_granularity粒度为8192,数据总量为8873898行。如果要下载测试数据如下所示

# download test datacurl https://clickhouse-datasets.s3.yandex.net/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv# new create tableclickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets"clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64,  JavaEnable UInt8,  Title String,  GoodEvent Int16,  EventTime DateTime,  EventDate Date,  CounterID UInt32,  ClientIP UInt32,  ClientIP6 FixedString(16),  RegionID UInt32,  UserID UInt64,  CounterClass Int8,  OS UInt8,  UserAgent UInt8,  URL String,  Referer String,  URLDomain String,  RefererDomain String,  Refresh UInt8,  IsRobot UInt8,  RefererCategories Array(UInt16),  URLCategories Array(UInt16), URLRegions Array(UInt32),  RefererRegions Array(UInt32),  ResolutionWidth UInt16,  ResolutionHeight UInt16,  ResolutionDepth UInt8,  FlashMajor UInt8, FlashMinor UInt8,  FlashMinor2 String,  NetMajor UInt8,  NetMinor UInt8, UserAgentMajor UInt16,  UserAgentMinor FixedString(2),  CookieEnable UInt8, JavascriptEnable UInt8,  IsMobile UInt8,  MobilePhone UInt8,  MobilePhoneModel String,  Params String,  IPNetworkID UInt32,  TraficSourceID Int8, SearchEngineID UInt16,  SearchPhrase String,  AdvEngineID UInt8,  IsArtifical UInt8,  WindowClientWidth UInt16,  WindowClientHeight UInt16,  ClientTimeZone Int16,  ClientEventTime DateTime,  SilverlightVersion1 UInt8, SilverlightVersion2 UInt8,  SilverlightVersion3 UInt32,  SilverlightVersion4 UInt16,  PageCharset String,  CodeVersion UInt32,  IsLink UInt8,  IsDownload UInt8,  IsNotBounce UInt8,  FUniqID UInt64,  HID UInt32,  IsOldCounter UInt8, IsEvent UInt8,  IsParameter UInt8,  DontCountHits UInt8,  WithHash UInt8, HitColor FixedString(1),  UTCEventTime DateTime,  Age UInt8,  Sex UInt8,  Income UInt8,  Interests UInt16,  Robotness UInt8,  GeneralInterests Array(UInt16), RemoteIP UInt32,  RemoteIP6 FixedString(16),  WindowName Int32,  OpenerName Int32,  HistoryLength Int16,  BrowserLanguage FixedString(2),  BrowserCountry FixedString(2),  SocialNetwork String,  SocialAction String,  HTTPError UInt16, SendTiming Int32,  DNSTiming Int32,  ConnectTiming Int32,  ResponseStartTiming Int32,  ResponseEndTiming Int32,  FetchTiming Int32,  RedirectTiming Int32, DOMInteractiveTiming Int32,  DOMContentLoadedTiming Int32,  DOMCompleteTiming Int32,  LoadEventStartTiming Int32,  LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32,  FirstPaintTiming Int32,  RedirectCount Int8, SocialSourceNetworkID UInt8,  SocialSourcePage String,  ParamPrice Int64, ParamOrderID String,  ParamCurrency FixedString(3),  ParamCurrencyID UInt16, GoalsReached Array(UInt32),  OpenstatServiceName String,  OpenstatCampaignID String,  OpenstatAdID String,  OpenstatSourceID String,  UTMSource String, UTMMedium String,  UTMCampaign String,  UTMContent String,  UTMTerm String, FromTag String,  HasGCLID UInt8,  RefererHash UInt64,  URLHash UInt64,  CLID UInt32,  YCLID UInt64,  ShareService String,  ShareURL String,  ShareTitle String,  ParsedParams Nested(Key1 String,  Key2 String, Key3 String, Key4 String, Key5 String,  ValueDouble Float64),  IslandID FixedString(16),  RequestNum UInt32,  RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192"# import datacat hits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.hits_v1 FORMAT TSV"# optionally you can optimize tableclickhouse-client --query "OPTIMIZE TABLE datasets.hits_v1 FINAL"

 

多个数据标记对应一个压缩数据块

多个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size小于64KB时,会出现这种对应关系。

以hits_v1测试表的JavaEnable字段为例。JavaEnable数据类型为UInt8,大小为1B,则一个间隔内数据大小为8192B。所以在此种情形下,每8个数据标记会对应同一个压缩数据块,如下图所示。

 

一个数据标记对应一个压缩数据块

一个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size大于等于64KB且小于等于1MB时,会出现这种对应关系。

以hits_v1测试表的URLHash字段为例。URLHash数据类型为UInt64,大小为8B,则一个间隔内数据大小为65536B,恰好等于64KB。所以在此种情形下,数据标记与压缩数据块是一对一的关系,如下图所示。

 

一个数据标记对应多个压缩数据块

一个数据标记对应多个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size直接大于1MB时,会出现这种对应关系。

以hits_v1测试表的URL字段为例。URL数据类型为String,大小根据实际内容而定。如下图所示,编号45的标记对应了2个压缩数据块。

 

 

结论

ClickHouse号称最快的OLAP型数据库不是空穴来风的,ClickHouse从OLAP场景需求出发,定制开发了一套全新的高效列式存储引擎,并且实现了数据有序存储、主键索引、二级索引、数据压缩和解压等丰富功能。以上功能共同为ClickHouse极速的分析性能奠定了基础。

 

参考资料

  • 《ClickHouse原理解析与应用实践》
    分享大数据行业的一些前沿技术和手撕一些开源库的源代码
    微信公众号名称:技术茶馆
    微信公众号ID    :    Night_ZW

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ClickHouse内核】对于分区、索引、标记和压缩数据的协同工作 的相关文章

  • 电商数据接口API深度解析

    随着电子商务的快速发展 电商平台之间的竞争也日益激烈 为了在市场中保持领先地位 电商平台需要不断地优化用户体验 提供个性化的服务和精准的推荐 而这一切都离不开数据 电商数据接口API作为一种高效 便捷的数据交互方式 被广泛应用于电商领域 本
  • Redis Geo:掌握地理空间数据的艺术

    欢迎来到我的博客 代码的世界里 每一行都是一个故事 Redis Geo 掌握地理空间数据的艺术 前言 Redis Geo基本概念 Geo模块的目的 工作原理 地理坐标系统
  • Nexus5596交换机支持3层需要的子卡

    3层子卡 nexus5596如果没有这块子卡 无法支持3层特性 TEST Cisco N5596 1 show modu Mod Ports Module Type Model Status 1 48 O2 32X10GBase T 16X
  • 实时获取建材网商品数据:API实现详解与代码示例

    一 引言 随着电子商务的快速发展 实时获取商品数据对于企业决策 市场分析以及数据驱动的营销策略至关重要 建材网作为国内知名的建材信息平台 提供了API接口 使得第三方开发者可以方便地获取商品数据 本文将详细介绍如何使用 建材网的API接口
  • python按列写入数据到excel

    要将数据按列写入 Excel 可以使用 Python 的 openpyxl 库 首先 需要安装 openpyxl 库 可以使用以下命令在终端或命令提示符中安装 pip install openpyxl 然后 可以按照以下步骤编写代码 1 导
  • AntDB内存管理之内存上下文之内存上下文机制是怎么实现的

    4 内存上下文机制是怎么实现的 下文将针对内存上下文机制进行代码说明 本次以AntDB的代码为例 来解析内存上下文的实现方式 4 1 最基础的数据结构 MemoryContextData和MemoryContextMethods是内存上下文
  • 亚信安慧AntDB引领数字化转型:浙江移动成功实现CRM系统全域改造

    数字时代 通信运营商在不断迭代的背景下 需要不断探索数字化转型的路径 以适应快速发展的市场和技术环境 在这一浪潮中 浙江移动站在前沿 率先完成了其CRM系统的全域改造 采用了亚信安慧公司研发的AntDB数据库 为整个行业树立了数字化转型的标
  • AntDB内存管理之内存上下文之如何使用内存上下文

    5 如何使用内存上下文 使用内存上下文之前 我们需要先对其进行创建 AntDB启动时已经创建并初始化好了部分内存上下文 例如 TopMemoryContext 这个TopMemoryContext是所有内存上下文的父节点或者祖先节点 一般我
  • 6 - 数据备份与恢复|innobackupex

    数据备份与恢复 innobackupex 数据备份与恢复 数据备份相关概念 物理备份与恢复 逻辑备份 推荐 使用binlog日志文件实现对数据的时时备份 使用日志 恢复数据
  • 【Mysql】InnoDB 引擎中的页目录

    一 页目录和槽 现在知道记录在页中按照主键大小顺序串成了单链表 那么我使用主键查询的时候 最顺其自然的办法肯定是从第一条记录 也就是 Infrimum 记录开始 一直向后找 只要存在总会找到 这种在数据量少的时候还好说 一旦数据多了 遍历耗
  • Clickhouse数据导入

    我在Clickhouse中创建了一个表 CREATE TABLE stock plant Int32 code Int32 service level Float32 qty Int32 ENGINE Log 有一个数据文件 head n
  • 图解python | 字符串及操作

    1 Python元组 Python的元组与列表类似 不同之处在于元组的元素不能修改 元组使用小括号 列表使用方括号 元组创建很简单 只需要在括号中添加元素 并使用逗号隔开即可 tup1 ByteDance ShowMeAI 1997 202
  • 基于java的饮食分享平台系统设计与实现

    基于java的饮食分享平台系统设计与实现 I 引言 A 研究背景和动机 近年来 随着人们生活水平的提高和健康意识的增强 饮食健康已经成为越来越多人的关注焦点 因此 一个方便快捷的饮食分享平台就显得尤为重要 基于Java的饮食分享平台系统设计
  • 软件测试|SQLAlchemy环境安装与基础使用

    简介 SQLAlchemy 是一个强大的 Python 库 用于与关系型数据库进行交互 它提供了高度抽象的对象关系映射 ORM 工具 允许使用 Python 对象来操作数据库 而不必编写原生SQL查询 本文将介绍如何安装 SQLAlchem
  • 电商数据api拼多多接口获取商品实时数据价格比价api代码演示案例

    拼多多商品详情接口 接口接入入口 它的主要功能是允许卖家从自己的系统中快速获取商品详细信息 通过这个接口 卖家可以提取到商品的各类数据 包括但不限于商品标题 价格 优惠价 收藏数 下单人数 月销售量等 此外 还可以获取到商品的SKU图 详情
  • 【计算机毕业设计】二手家电管理平台

    时代在飞速进步 每个行业都在努力发展现在先进技术 通过这些先进的技术来提高自己的水平和优势 二手家电管理平台当然不能排除在外 二手家电管理平台是在实际应用和软件工程的开发原理之上 运用java语言以及前台VUE框架 后台SpringBoot
  • 【计算机毕业设计】OA公文发文管理系统_xtv98

    近年来 人们的生活方式以网络为主题不断进化 OA公文发文管理就是其中的一部分 现在 无论是大型的还是小型的网站 都随处可见 不知不觉中已经成为我们生活中不可或缺的存在 随着社会的发展 除了对系统的需求外 我们还要促进经济发展 提高工作效率
  • MongoDB - 库、集合、文档(操作 + 演示 + 注意事项)

    目录 一 MongoDB 1 1 简介 a MongoDB 是什么 为什么要使用 MongoDB b 应用场景 c MongoDB 这么强大 是不是可以直接代替 MySQL d MongoDB 中的一些概念 e Docker 下载 1 2
  • 每日变更的最佳实践

    在优维公司内部 我们采用发布单的方式进行每天的应用变更管理 这里给各位介绍优维的最佳实践 变更是需要多角色合作的 而且他是整体研发流程的一部分 在优维内部 我们坚持每日变更 打通开发环节到最终发布上线的全过程 在保证质量的前提下 尽可能提升
  • 在 Spark 中将带有 MapType 列的 DataFrame 写入数据库

    我正在尝试使用 clickhouse native jdbc 驱动程序将带有 MapType 列的数据帧保存到 Clickhouse 架构中也包含地图类型列 并遇到以下错误 Caused by java lang IllegalArgume

随机推荐

  • GAN生成手写数字实例讲解Colab使用教程

    Colab 全称Colaboratory 是谷歌提供的一个在线工作平台 可以与谷歌云盘协作使用 我们可以在Colab平台上运行代码 而且大部分常用的包都已经安装好 不需要再进行安装 也不需要进行环境配置 非常方便快捷 对于初学者来说非常友好
  • 颠覆传统逻辑的C程序

    1 在main之前运行的C代码 before main c include
  • k8s 部署spring cloud项目

    微服务架构是一项在云中部署应用和服务的新技术 大部分围绕微服务的争论都集中在容器或其他技术是否能很好的实施微服务 而红帽说API应该是重点 微服务可以在 自己的程序 中运行 并通过 轻量级设备与HTTP型API进行沟通 关键在于该服务可以在
  • LouvainMethod分布式运行的升级之路

    1 背景介绍 Louvain是大规模图谱的谱聚类算法 引入模块度的概念分二阶段进行聚类 直到收敛为止 分布式的代码可以在如下网址进行下载 GitHub Sotera spark distributed louvain modularity
  • Windows下SpringBoot连接Redis的正确使用姿势

    1 安装Redis 1 1通过wsl安装redis 参考官方安装文档 需要在wsl2上安装redis服务 注意我们启动redis的方式 First way 采用官方文档的方式 sudo service redis server start
  • Python自学——The One Day(Python基础——介绍)

    文章目录 Python基础 介绍 前言 编译型语言和解释型语言 Python是什么 Python的优缺点是什么 优点 缺点 Python的运行过程 Python能干什么 怎样学好Python Python基础 介绍 前言 编译型语言和解释型
  • 2014年10月4399校招笔试--游戏岗

    今天参加了4399的笔试 总的来说题目不难 不过有些题没答上来 特别是选择题最后几个关于图像的题目22 25 真心不会
  • vivado中的常用AXI接口IP核

    AXI是xilinx中常用的数据接口 种类和引脚数量极多 1 AXI GPIO AXI GPIO为AXI接口提供了一个通用的输入 输出接口 可以配置成单通道和双通道 每个通道的位宽都可以单独设置 另外 通过打开或者关闭三通道缓冲器 AXI
  • 使用 ST-LINK 烧录程序到 STM32

    前言 之前博主在使用单片机时 烧录程序用的都是串口的方式 最近公司定制了一个工业版单片机目前只支持使用 ST LINK 烧录 因此博主收集了一些资料 并整理了烧录程序的流程用于分享和后期自己回顾 准备工作 准备烧录编程器 博主直接在网上买了
  • 图像仿射变换原理4:组合变换及对应变换矩阵

    老猿Python博文目录 https blog csdn net LaoYuanPython 仿射变换博文传送门 带星号的为付费专栏文章 图像仿射变换原理1 齐次坐标来龙去脉详解 图像仿射变换原理2 矩阵变换 线性变换和图像线性变换矩阵 图
  • Linux下 VS Code 安装与 C 编程环境配置!

    对于多文件的C项目 大部分人会选择使用 cmake 来管理编译过程 对于精力充沛的朋友来说 也可以学习一下使用这个强大的工具 但我觉得如果只想在VS Code里写几行代码应对当前需求 没必要再去学习一个完全陌生的东西 也没必要把配置过程复杂
  • 捕鱼游戏java源码

    package fishlord import java awt Color import java awt Font import java awt Graphics import java awt event MouseAdapter
  • eclipse 报错 java.lang.NullPointerException at org.eclipse.jface.resource.JFaceResources.getResources

    java lang NullPointerException at org eclipse jface resource JFaceResources getResources JFaceResources java 209 删除文件 wo
  • MySQL——流程控制(IF、CASE、LOOP、WHILE、REPEAT、LEAVE、ITERATE)

    解决复杂问题不可能通过一个 SQL 语句完成 我们需要执行多个 SQL 操作 流程控制语句的作用就是控制存储过程中 SQL 语句的执行顺序 是我们完成复杂操作必不可少的一部分 接下来让我们一起开始学习吧 流程控制 只要是执行的程序 流程就分
  • Java基础学习之并发篇:手写阻塞队列ArrayBlockingQueue

    学习目标 我们都知道在并发编程中 阻塞队列在多线程中的场景特别有用 比如在生产和消费者模型中 生产者生产数据到队列 队列满时需要阻塞线程 停止生产 消费者消费队列 对队列为空时阻塞线程停止消费 在Java中有提供不同场景的阻塞队列 那么接下
  • bilbili自动点赞脚本(python)开发

    前言 现在bilibili成了我们许多年轻人喜欢去的地方 那里有丰富的资源 好看的小姐姐 稀有的资源 会玩的大佬 还有许多不为人知的地方 这是一个和谐安康的世界 人们在这儿幸福的生活 但有一天 一切都变了 纯净的世界被恶龙所污染 弹幕区素质
  • 新手必读:Arduino UNO R3教程,原理图,引脚图,详细介绍

    刚入门的学习Arduino的朋友都会有个疑问Arduino UNO R3是什么 为什么要从Arduino UNO R3开始学起 Arduino概述 Arduino是一个开放源码电子原型平台 拥有灵活 易用的硬件和软件 Arduino专为设计
  • JAVA--位运算

    java的位运算 什么是位运算 位运算符就是在二进制的情况下对bit位的运算 在计算机当中 数字都是由二进制构成 由一串0或1构成 一个字节是由八位0或1构成 所以一般情况下都是由八位构成 但是最高位都是符号位0为正数1为负数 比如 8 0
  • 解决用Fiddler抓包,网页显示你的连接不是专用/私密连接

    一 在Fiddler安装证书 1 Tools gt Options gt HTTPS gt 勾选Capture HTTPS CONNECTs gt 勾选Decrypt HTTPS trafic gt 弹窗一路yes 如果没有弹窗 则Acti
  • 【ClickHouse内核】对于分区、索引、标记和压缩数据的协同工作

    目录 概述 写入过程 生成分区目录 生成索引 生成标记和数据压缩文件 各个底层物理文件生成的过程 查询过程 借助索引文件降低扫描范围 借助标记文件降低解压数据的大小 数据标记与压缩数据块的对应关系 多个数据标记对应一个压缩数据块 一个数据标