告别等待,秒级响应!这不只是教程,这是你驾驭PB级数据的超能力!我的ClickHouse视频课,凝练十年实战精华,从入门到精通,从单机到集群。点开它,让数据处理速度快到飞起,让你的职业生涯从此开挂!

全套视频教程联系博主 :试听视频位置

主键索引 (稀疏索引) 的工作原理

  1. 核心概念:稀疏索引 (Sparse Index)

与 MySQL 等数据库为每一行数据都建立索引(密集索引)不同,ClickHouse 的主键索引是稀疏的。它只为每个数据颗粒(Granule)的第一行记录一个“路标”。

  • 数据颗粒 (Granule):ClickHouse 在存储数据时,会将表中的行分批打包,一个包就是一个 Granule。默认情况下,一个 Granule 包含 8192 行。

  • 索引文件 (primary.idx):这个文件非常小,因为它只存储每个 Granule 的“路标”值。例如,如果 ORDER BY(event_date),那么索引文件里存的就是每个 Granule 的起始日期。

图示

 

  1. 查询来了WHERE event_date = '2023-10-03'

  2. 扫描索引:ClickHouse 快速扫描内存中的 primary.idx 文件。

  3. 定位范围:它发现 '2023-10-03' 这个值介于路标2 ('2023-10-03') 和路标3 ('2023-10-05') 之间。这意味着,目标数据 只可能存在于 Granule 2 中

  4. 精确打击:ClickHouse 直接跳过 Granule 1 和 Granule 3,只从磁盘读取 Granule 2 这一个数据块进行处理。

结论:稀疏索引的威力在于大幅减少 I/O。它不关心数据具体在哪一行,只关心数据在哪一个数据块范围内。

主键索引的设计要点:

  • 列的选择ORDER BY 的列应该是你 WHERE 子句中最常用的过滤条件,尤其是范围查询(>, <, BETWEEN)。

  • 列的顺序:把基数更高(筛选能力更强)的列放在前面。例如 ORDER BY (event_date, user_id) 就比 ORDER BY (user_id, event_date) 要好,因为日期能先过滤掉大量不相关的数据块。

我们再强调一次:ClickHouse 的主键索引是稀疏的。它不像 MySQL 那样为每一行都建索引。它只为每个数据颗粒(Granule,默认8192行) 的第一行建立一条索引记录。

优点:索引文件非常小,可以常驻内存。 工作方式:查询时,ClickHouse 在内存中快速扫描索引,定位到可能包含目标数据的 Granule 范围,然后只把这些 Granule 从磁盘加载到内存中进行精确匹配。

【实践】: 为表添加跳数索引

给刚才的 user_behavior 表的 url 列添加一个布隆过滤器索引,以加速特定URL的查找。

-- 在建表时添加
CREATE TABLE user_behavior_with_index (-- ... 其他列定义和上面一样 ...url                 String,-- ...INDEX idx_url url TYPE bloom_filter() GRANULARITY 1 -- GRANULARITY表示索引的粒度
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, event_type, user_id);-- 查询时,ClickHouse会自动使用该索引
-- 这个查询会因为idx_url索引而变得更快
SELECT count()
FROM user_behavior_with_index
WHERE url = 'https://clickhouse.com/docs/en/';

 数据跳过索引 (Skipping Indexes)-Granule 的“智能标签”

如果说主键索引是城市间的高速公路,那么数据跳过索引就是每个高速出口旁边的信息指示牌。它告诉你这个出口下去的区域“有什么”和“没有什么”,帮你决定是否要下高速。

数据跳过索引是附加在每个数据颗粒 (Granule) 上的元数据。它独立于主键索引,用于对非主键列进行预过滤。

除了主键,ClickHouse 还提供了额外的“跳数索引”,它们像给数据颗粒贴上的“标签”,进一步减少需要扫描的数据量。

  • minmax: 记录每个颗粒内某列的最大最小值。如果查询 WHERE price > 500,而某个颗粒的 minmax 标签是 [100, 400],则可以直接跳过。

  • set(N): 记录每个颗粒内某列的前N个唯一值。如果查询 WHERE color = 'Red',而某个颗粒的 set 标签是 {'Blue', 'Green'},则可以跳过。

  • bloom_filter: 一种概率性索引。如果你查询 WHERE has(urls, 'some_rare_url'),布隆过滤器可以快速告诉你“这个颗粒绝对没有这个URL”,从而跳过。它可能会误报(说有但实际没有),但绝不会漏报。

① minmax
  • 作用:记录每个 Granule 中某一列的最小值和最大值。

  • 场景:非常适合数值或日期类型。

  • 原理:查询 WHERE price > 1000。如果某个 Granule 的 minmax 标签是 [100, 900],ClickHouse 就知道这个 Granule 内所有 price 都小于等于900,不可能满足条件,于是直接跳过。

 

图解:查询 price > 1000 时,Granule 1 被直接跳过,因为它的最大值 900 都不满足条件。Granule 2 和 Granule 3 因为范围有交集,所以需要被读取。

② set(N)
  • 作用:记录每个 Granule 中某列的前 N 个唯一值

  • 场景:适合基数较低的 StringEnum 列,用于等值查询。

  • 原理:查询 WHERE city = 'Shanghai'。如果某个 Granule 的 set(3) 标签是 {'Beijing', 'Guangzhou', 'Shenzhen'},ClickHouse 就知道这个 Granule 里根本没有 'Shanghai',直接跳过。

③ bloom_filter
  • 作用:一种概率性数据结构,可以非常确定地判断一个元素“绝对不存在”,但只能概率性地判断“可能存在”

  • 场景

    • 高基数的 String 列(如 URL,用户ID)。

    • 检查数组中是否包含某个元素 has(array, 'value')

    • 检查 Map 中是否存在某个键 mapContains(map, 'key')

  • 原理:它像一个“黑名单筛选器”。数据写入时,把 Granule 里的值都扔进布隆过滤器。查询时,先问布隆过滤器:“这个值在你的黑名单上吗?”

    • 如果回答“不在”(即绝对不存在),则安全跳过

    • 如果回答“可能在”(有可能是误报),则需要读取 Granule 进一步确认

 

图解:查询 'e.com' 时,布隆过滤器 1 准确地告诉我们 Granule 1 中没有,从而避免了一次 I/O。布隆过滤器 2 提示可能存在,我们就需要去读取 Granule 2 来做最终的判断。

【实践】: 为表添加跳数索引

 

CREATE TABLE access_logs (event_time  DateTime,request_id  String,http_code   UInt16,url         String
) ENGINE = MergeTree()
ORDER BY (event_time)
SETTINGS index_granularity = 8192; -- 明确指定颗粒大小-- 为 request_id 和 http_code 添加跳数索引
ALTER TABLE access_logs ADD INDEX idx_req_id request_id TYPE bloom_filter() GRANULARITY 4;
ALTER TABLE access_logs ADD INDEX idx_code http_code TYPE set(0) GRANULARITY 4;

GRANULARITY 4:表示这个跳数索引的粒度是主索引的 4 倍。即每 4 * 8192 行数据,才生成一个跳数索引块。这是一种在索引精度和大小之间的权衡。

2. 验证索引是否生效: 使用 EXPLAIN 或查询日志 system.query_log 是最好的方法。我们用一个更直观的方式:trace_logging

-- 执行带 trace_logging 的查询
SELECT count()
FROM access_logs
WHERE request_id = 'some-very-specific-request-id-abcdef'
SETTINGS log_queries=1; -- 确保查询被记录-- 在执行查询后,立刻查看日志
-- 在 clickhouse-server.log 文件中,或者在 system.query_log 表中查找
-- 你会看到类似这样的日志:
/*
<Trace> MergeTree(Reading): Mark ranges: [0, 1]
<Trace> MergeTree(Reading): Selected 1/100 parts by partition key
<Trace> MergeTree(Reading): Selected 1/50 ranges by primary key
<Trace> MergeTree(Reading): Selected 5/20 granules by skipping indexes -- 关键!
*/

日志中的 Selected ... granules by skipping indexes 明确告诉你,数据跳过索引生效了!它帮助 ClickHouse 在主键筛选之后,又进一步排除了更多的 Granule。

总结与最佳实践

  1. 主键索引是基石ORDER BY 决定了数据的大方向,是性能优化的第一道防线。

  2. 跳数索引是精细化武器:它在主键索引筛选后的“候选范围”内,进行二次精准打击,进一步减少 I/O。

  3. 按需索骥:不要滥用索引!每个索引都会在写入时带来额外的计算开销,并占用存储空间。只为那些真正能大幅缩小查询范围的列创建索引。

  4. 如何选择?

    1. 数值/日期范围查询 -> minmax

    2. 低基数 String/Enum 等值查询 -> set

    3. 高基数 String 等值查询或 has() / mapContains() -> bloom_filter

掌握了主键索引和数据跳过索引的组合拳,你就掌握了开启 ClickHouse 极致性能的钥匙。现在,去锻造你自己的“神兵利器”吧!

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

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

相关文章

Jetpack - Room(Room 引入、Room 优化)

一、Room 引入 1、基本介绍 Room 在 SQLite 上提供了一个抽象层&#xff0c;以便在充分利用 SQLite 的强大功能的同时&#xff0c;能够流畅地访问数据库&#xff0c;官方强烈建议使用 Room 而不是 SQLite 2、演示 &#xff08;1&#xff09;Setting 模块级 build.gradle depend…

【江科大CAN】2.1 STM32 CAN外设(上)

2.1 STM32 CAN外设&#xff08;上&#xff09;2.1.1 STM32 CAN外设简介2.1.2 外围电路设计2.1.3 STM32 CAN内部结构2.1.4 发送流程详解2.1.5 接收流程详解2.1.6 关键配置位总结STM32 CAN外设讲解 大家好&#xff0c;欢迎继续观看CAN总线入门教程。本节开始&#xff0c;我们正式…

人工智能技术革命:AI工具与大模型如何重塑开发者工作模式与行业格局

引言&#xff1a;AI技术爆发的时代背景过去五年间&#xff0c;人工智能领域经历了前所未有的爆发式增长。从2020年GPT-3的横空出世到2023年多模态大模型的全面突破&#xff0c;AI技术已经从实验室走向了产业应用的前沿。开发者作为技术生态的核心推动者&#xff0c;其工作模式正…

傅里叶变换

傅里叶变换:运用频域的出发点就是能够将波形从时域变换到频域&#xff0c;用傅里叶变换可以做到这一点。有如下3种傅里叶变换类型&#xff1a;1.傅里叶积分(FI); 2.离散傅里叶变换(DFT); 3.快速傅里叶变换(FFT)。傅里叶积分是一种将时域的理想数学表达变换成频域描述的数学技术…

【IQA技术专题】纹理相似度图像评价指标DISTS

纹理一致性图像评价指标: Image Quality Assessment: Unifying Structure and Texture Similarity&#xff08;2020 PAMI&#xff09;专题介绍一、研究背景二、方法总览2.1 初始变换2.2 纹理表示和结构表示2.3 DISTS指标2.4 优化DISTS指标三、实验结果四、总结本文将对统一图像…

windows下Docker安装路径、存储路径修改

一、命令行指定安装路径​ ​​下载安装包​​&#xff1a;从Docker官网获取安装程序&#xff08;如Docker Desktop Installer.exe&#xff09;。​​运行PowerShell​​&#xff1a; & "H:\Docker Desktop Installer.exe" install --installation-dir"F:…

thingsboard 自定义动作JS编程

在 ThingsBoard 中实现 自定义动作&#xff08;Custom Action&#xff09;的 JavaScript 编程&#xff0c;主要通过“Custom action (with HTML template&#xff09;”方式完成&#xff0c;适用于创建弹窗、编辑实体、控制设备等交互行为。 实现步骤&#xff08;以添加设备或资…

Spring Boot 简单接口角色授权检查实现

一、背景与目标在Spring Boot应用开发中&#xff0c;接口级别的权限控制是系统安全的重要组成部分。本文将介绍一种简单直接的接口角色授权检查实现方案&#xff0c;适合快速开发和安全合规检查场景。二、技术方案概述本方案采用自定义注解拦截器的方式实现&#xff0c;具有以下…

PytorchLightning最佳实践日志篇

在 PyTorch Lightning&#xff08;PL&#xff09;中&#xff0c;日志系统是 “炼丹” 过程中复现实验、对比效果、排查问题的核心工具。结合实际工程经验&#xff0c;总结以下最佳实践和技巧&#xff0c;帮助提升实验效率&#xff1a; 一、日志工具的选择与配置 PL 通过统一的s…

基于JavaWeb的兼职发布平台的设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.6系统展示系统首页用户登录招聘信…

Linux学习--C语言(指针3)

1.指针函数和函数指针1.1 指针函数指针函数是函数&#xff0c;函数的返回值是指针不能返回局部变量的地址指针函数返回的地址可以作为下一个函数调用的参数1.2 函数指针函数指针是指针&#xff0c;指针指向一个函数#include <stdio.h>int Add(int x, int y) {return x y…

【JAVA EE初阶】多线程(上)

目录 1.预备知识 1.1 冯诺依曼体系结构&#xff1a; 1.2 现代CPU主要关心指标&#xff08;和日常开发密切相关的&#xff09; 1.3 计算机中&#xff0c;一个汉字占几个字节&#xff1f; 1.4 Windows和Linux的区别 1.5 PCB的一些关键要点 2.线程和进程 2.1 创建线程的写法…

用互联网思维扩展电商后台的 CRUD 功能

一、自定义实现MyBatis-Plus逆向工程 多数据源的问题解决了&#xff0c;接下来开始进行实际开发时&#xff0c;你会发现&#xff0c;最麻烦的一件事情就是要创建与数据库表对应的POJO了。这些没什么难度&#xff0c;但是繁琐的内容会占据大量的开发时间。比如一个PmsProducr对…

无代码测试平台ATECLOUD全场景测试方案

ATECLOUD 智能云测试平台是有纳米软件开发的一款以无代码架构与弹性扩展体系为核心的自动化测试平台&#xff0c;通过数据模型驱动的创新设计&#xff0c;为研发、产线等多场景提供高效可控的测试解决方案。​无代码架构 ATECLOUD 打破传统技术壁垒&#xff0c;构建完全可视化的…

当 AI 重构审计流程,CISA 认证为何成为破局关键

在南京审计大学最新发布的《面向审计行业 DeepSeek 大模型操作指南》中&#xff0c;一组数据引发行业深思&#xff1a;通过自动化数据处理、智能风险识别和定制化报告生成&#xff0c;AI 大模型能帮助审计人员降低 40% 以上的人工成本&#xff0c;同时将风险识别准确率提升至 9…

NAT技术、代理服务器

NAT/NAPT技术NAT的全称是network address translation&#xff0c;网络地址转换。NAT 能在对外通信时够将源 IP 转为新源 IP&#xff0c;对内通信时将目的ip转换成新目的ip&#xff0c;实现这个操作&#xff0c;靠的是地址转换表但NAT的说法其实是不准确的&#xff0c;因为多个…

【硬件-笔试面试题】硬件/电子工程师,笔试面试题-45,(知识点:负反馈的作用,基础理解,干扰和噪声的抑制)

目录 1、题目 2、解答 步骤一&#xff1a;明确负反馈的作用原理 步骤二&#xff1a;逐一分析选项 3、相关知识点 一、负反馈的基本原理 二、负反馈对干扰和噪声的抑制机制 三、选项分析与答案 四、扩展思考&#xff1a;如何抑制不同位置的干扰&#xff1f; 总结 题目…

Flutter蓝牙BLE开发完全指南(内含高级功能扩展)

Flutter蓝牙BLE开发完全指南 我将为您提供一个完整的Flutter蓝牙BLE实现方案,包含UI设计、权限处理、设备扫描、连接通信等完整功能。 完整实现方案 1. 添加依赖与权限配置 pubspec.yaml dependencies:flutter:sdk: flutterflutter_blue_plus: ^1.10.0permission_handler…

使用 Canvas 替代 <video> 标签加载并渲染视频

在部分浏览器环境或业务场景下&#xff0c;直接使用 <video> 标签加载视频会出现首帧延迟的情况。以下方法通过 WebGPU Canvas 2D 将视频帧绘制到自定义 Canvas 上&#xff0c;让 <video> 只做解码&#xff0c;WebGPU 接管渲染&#xff0c;通过最小化对象创建 精…

基于Flask的智能停车场管理系统开发实践

在现代城市中&#xff0c;停车难已成为一个普遍问题。为了解决这一问题&#xff0c;我开发了一个基于Python Flask框架的智能停车场管理系统。该系统集成了车牌识别、车位状态监控、收费管理等多项功能&#xff0c;为停车场的智能化管理提供了完整的解决方案。系统功能概述该停…