ClickHouse index_granularity 详解 - 若

news/2025/9/24 11:49:24/文章来源:https://www.cnblogs.com/zhanchenjin/p/19108871

ClickHouse index_granularity 详解

什么是 index_granularity

index_granularity 是ClickHouse中一个重要的性能配置参数,它定义了索引的粒度(granularity),即每多少个数据行会创建一个索引标记(index mark)。

基本概念

1. 索引标记的工作原理

数据行: [1, 2, 3, ..., 8192] [8193, 8194, ..., 16384] [16385, 16386, ...]
索引标记:      ↑标记1              ↑标记2              ↑标记3
  • 每8192行数据创建一个索引标记
  • 每个标记存储该段数据的边界信息(最小值、最大值等)
  • 查询时先通过索引标记快速定位到可能包含目标数据的段

2. 索引标记的创建依据

索引标记是根据ORDER BY子句中定义的列来创建的:

CREATE TABLE blocks (block_number UInt64,timestamp DateTime,block_hash String
) ENGINE = MergeTree()
ORDER BY (block_number, timestamp)  -- 索引标记基于这两列创建
SETTINGS index_granularity = 8192;

索引标记存储的信息:

  • 最小值:该段数据中ORDER BY列的最小值
  • 最大值:该段数据中ORDER BY列的最大值
  • 行数:该段包含的行数
  • 数据块位置:指向实际数据块的指针

3. 索引查找过程示例

-- 查询区块号范围
SELECT * FROM blocks WHERE block_number BETWEEN 10000 AND 20000;

索引查找过程:

  1. 检查索引标记1:max=8192 < 10000,跳过
  2. 检查索引标记2:min=8193, max=16384,与查询范围重叠,需要读取
  3. 检查索引标记3:min=16385 > 20000,跳过
  4. 只读取索引标记2对应的数据块

ORDER BY 对索引的影响

1. 不同ORDER BY的影响

单列排序:

ORDER BY block_number
-- 索引标记基于block_number创建
-- 适合按区块号查询

多列排序:

ORDER BY (block_number, timestamp)
-- 索引标记基于(block_number, timestamp)组合创建
-- 适合复合查询条件

你的表结构:

ORDER BY (start_block, end_block)
-- 索引标记基于(start_block, end_block)组合创建
-- 适合按区块范围查询

2. 索引效率的关键因素

ORDER BY列的选择:

-- 好的选择:经常用于WHERE条件的列
ORDER BY (block_number, timestamp)-- 不好的选择:很少用于查询的列
ORDER BY (random_column, unused_column)

列的顺序:

-- 好的顺序:选择性高的列在前
ORDER BY (block_number, timestamp)  -- block_number选择性高-- 不好的顺序:选择性低的列在前
ORDER BY (status, block_number)     -- status选择性低

查询模式匹配(左侧匹配原则):

-- 表结构
ORDER BY (start_block, end_block, status)-- 高效查询(遵循左侧匹配)
WHERE start_block = 12345                                    -- ✅ 使用第1列
WHERE start_block = 12345 AND end_block = 12350             -- ✅ 使用第1、2列
WHERE start_block = 12345 AND end_block = 12350 AND status = 'finished'  -- ✅ 使用第1、2、3列
WHERE start_block BETWEEN 1000 AND 2000                     -- ✅ 范围查询也遵循左侧匹配-- 低效查询(违反左侧匹配)
WHERE end_block = 12350                                     -- ❌ 跳过第1列,直接使用第2列
WHERE status = 'finished'                                   -- ❌ 跳过第1、2列,直接使用第3列
WHERE start_block = 12345 AND status = 'finished'          -- ❌ 使用第1、3列,跳过第2列

左侧匹配原则详解

1. 基本原理

ClickHouse的索引遵循左侧匹配原则,类似于MySQL的复合索引。查询时必须从左到右使用ORDER BY中的列,不能跳过中间的列。

2. 与MySQL的对比

-- MySQL复合索引:(start_block, end_block, status)
-- 遵循左侧匹配原则-- ClickHouse ORDER BY:(start_block, end_block, status)  
-- 同样遵循左侧匹配原则

3. 索引标记的工作原理

-- 表结构:ORDER BY (start_block, end_block, status)-- 索引标记存储:
标记1: start_block_min=1, start_block_max=1000, end_block_min=1, end_block_max=1000, status_min='init', status_max='pending'
标记2: start_block_min=1001, start_block_max=2000, end_block_min=1001, end_block_max=2000, status_min='init', status_max='pending'

4. 查询效率分析

-- ✅ 高效查询:WHERE start_block = 1500
-- 可以快速定位到标记2,因为start_block在范围内-- ❌ 低效查询:WHERE end_block = 1500  
-- 无法有效使用索引,因为索引标记的end_block范围重叠
-- 需要扫描多个标记或全表扫描

5. 实际应用示例

-- 你的block_tasks表
CREATE TABLE block_tasks (start_block UInt64,end_block UInt64,status String
) ENGINE = MergeTree()
ORDER BY (start_block, end_block)
SETTINGS index_granularity = 8192;-- 高效查询模式
SELECT * FROM block_tasks WHERE start_block = 12345;                    -- ✅ 使用第1列
SELECT * FROM block_tasks WHERE start_block BETWEEN 1000 AND 2000;      -- ✅ 范围查询第1列
SELECT * FROM block_tasks WHERE start_block = 12345 AND end_block = 12350; -- ✅ 使用第1、2列-- 低效查询模式  
SELECT * FROM block_tasks WHERE end_block = 12350;                      -- ❌ 跳过第1列
SELECT * FROM block_tasks WHERE status = 'finished';                    -- ❌ 跳过第1、2列

6. 最佳实践

-- 设计ORDER BY时要考虑查询模式
-- 将最常用于WHERE条件的列放在前面
ORDER BY (最常用的列, 次常用的列, 较少用的列)-- 例如:如果经常按start_block查询,偶尔按start_block+end_block查询
ORDER BY (start_block, end_block)  -- 好的设计-- 如果经常按end_block查询,偶尔按start_block查询  
ORDER BY (end_block, start_block)  -- 更好的设计

默认值和推荐值

  • 默认值:8192
  • 推荐值:8192(ClickHouse官方推荐)
  • 常见值:1024, 4096, 8192, 16384, 65536

不同值的影响

index_granularity 内存使用 查询速度 写入速度 适用场景
1024 (小) 频繁更新,查询较少
4096 (中小) 较高 较慢 较快 平衡型应用
8192 (默认) 中等 中等 通用场景,推荐
16384 (大) 较低 中等 较慢 批量写入,查询频繁
65536 (很大) 中等 大批量数据,查询较少

为什么选择 8192

1. 数学优势

  • 2的幂次方:8192 = 2^13,便于计算机处理
  • 内存对齐:与系统页面大小(8KB)匹配
  • 缓存友好:适合CPU缓存行大小

2. 性能平衡

  • 查询性能:能够快速定位到相关数据段
  • 内存使用:不会创建过多索引标记
  • 写入性能:在批量插入时保持良好的性能

3. 经验优化

  • ClickHouse团队经过大量测试得出的最佳值
  • 适用于大多数应用场景
  • 平衡了各种性能指标

实际应用示例

1. 区块数据表

CREATE TABLE blocks (block_number UInt64,timestamp DateTime,block_hash String
) ENGINE = MergeTree()
ORDER BY (block_number, timestamp)
SETTINGS index_granularity = 8192;

查询示例:

-- 查询特定区块范围
SELECT * FROM blocks WHERE block_number BETWEEN 1000000 AND 1001000;

性能分析:

  • 100万行数据,8192粒度,约122个索引标记
  • 查询时只需检查122个标记,然后读取对应的8192行数据段
  • 相比全表扫描,性能提升显著

2. 交易数据表

CREATE TABLE transactions (tx_hash String,block_number UInt64,from_address String,to_address String
) ENGINE = MergeTree()
ORDER BY (block_number, tx_hash)
SETTINGS index_granularity = 8192;

3. 日志数据表

CREATE TABLE logs (block_number UInt64,log_index UInt32,address String,data String
) ENGINE = MergeTree()
ORDER BY (block_number, log_index)
SETTINGS index_granularity = 8192;

如何选择合适的值

1. 数据量考虑

-- 小表(<10万行):使用较小值
SETTINGS index_granularity = 1024;-- 中等表(10万-1000万行):使用默认值
SETTINGS index_granularity = 8192;-- 大表(>1000万行):使用较大值
SETTINGS index_granularity = 16384;

2. 查询模式考虑

-- 频繁点查询:使用较小值
SETTINGS index_granularity = 4096;-- 范围查询为主:使用默认值
SETTINGS index_granularity = 8192;-- 批量查询:使用较大值
SETTINGS index_granularity = 16384;

3. 写入模式考虑

-- 频繁小批量写入:使用较小值
SETTINGS index_granularity = 4096;-- 批量写入:使用默认值
SETTINGS index_granularity = 8192;-- 大批量写入:使用较大值
SETTINGS index_granularity = 32768;

性能测试示例

1. 查询性能对比

-- 测试不同粒度的查询性能
-- 数据量:1000万行
-- 查询:WHERE block_number BETWEEN 1000000 AND 1001000-- index_granularity = 1024
-- 索引标记数:约9766个
-- 查询时间:较慢-- index_granularity = 8192  
-- 索引标记数:约1221个
-- 查询时间:快-- index_granularity = 65536
-- 索引标记数:约153个  
-- 查询时间:中等

2. 内存使用对比

-- 索引标记内存使用估算
-- 每个标记约占用几十字节-- 1000万行数据:
-- 1024粒度:约9766个标记,内存使用高
-- 8192粒度:约1221个标记,内存使用中等
-- 65536粒度:约153个标记,内存使用低

最佳实践

1. 默认配置

-- 大多数情况下使用默认值
SETTINGS index_granularity = 8192;

2. 特殊场景调整

-- 高并发点查询
SETTINGS index_granularity = 4096;-- 大批量数据写入
SETTINGS index_granularity = 16384;-- 内存受限环境
SETTINGS index_granularity = 32768;

3. 监控和调优

-- 查看表设置
SELECT * FROM system.tables WHERE name = 'your_table';-- 监控查询性能
SELECT * FROM system.query_log 
WHERE query LIKE '%your_table%' 
ORDER BY event_time DESC;

常见问题

Q: 如何确定最佳值?

A: 通过性能测试,监控查询时间和内存使用,选择平衡点。

Q: 可以动态调整吗?

A: 不可以,需要在创建表时设置,修改需要重建表。

Q: 不同表可以使用不同值吗?

A: 可以,每个表可以独立设置。

Q: 设置过小会有什么问题?

A: 内存使用增加,写入性能下降。

Q: 设置过大会有什么问题?

A: 查询时需要扫描更多数据,查询性能下降。

总结

index_granularity = 8192 是ClickHouse的推荐配置,它在查询性能、内存使用和写入性能之间达到了很好的平衡。

关键要点

  1. 索引基于ORDER BY列:索引标记是根据ORDER BY子句中定义的列创建的
  2. 左侧匹配原则:查询时必须从左到右使用ORDER BY中的列,不能跳过中间的列
  3. 查询匹配很重要:WHERE条件应该尽量使用ORDER BY列,以获得最佳性能
  4. 列顺序影响效率:选择性高的列应该放在ORDER BY的前面
  5. 默认值适用大多数场景:8192是经过优化验证的最佳选择

Web3数据收集项目应用

  1. 区块数据:使用默认值8192,适合范围查询
  2. 交易数据:使用默认值8192,平衡查询和写入
  3. 日志数据:使用默认值8192,适合批量查询
  4. 任务管理:ORDER BY (start_block, end_block) 配合8192粒度,高效支持任务查询

除非有特殊需求,否则建议使用默认值8192,这是经过优化验证的最佳选择。

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

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

相关文章

PADS笔记

PADS笔记PCB设计流程准备--功能确定、元器件选型 元件库建立-元器件符号、器件封装 绘制原理图-根据电路功能,将元器件符号进行连接 导出网络表--将元器件的连接关系,以及元器件的信息导出一个文件,以方便导入到其他…

【2025最新教程】Claude Code国内使用_保姆级新手安装使用教程_最强AI编程工具

【2025最新教程】Claude Code国内使用_保姆级新手安装使用教程_最强AI编程工具什么是 Claude Code Claude Code 是 Anthropic 推出的一个 agentic 编码工具 (agentic coding tool),可以在命令行(terminal)中运行,或…

如何计算sequence粒度的负载均衡损失 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P13885 [蓝桥杯 2023 省 Java/Python A] 反异或 01 串

发现操作完后必定为一个回文串,并且至多消去区间一半数量的 \(1\),求最长回文串即可。

获取网站缩略图的asp代码wordpress的cms主题

防火墙在解决方案及典型项目中的应用 防火墙作为基础安全防护产品&#xff0c;在各种解决方案、业务场景中配套应用&#xff0c;本节给出各类方案资料链接方便查阅。 防火墙在华为网络解决方案中的应用 解决方案 文档 主要应用 CloudFabric云数据中心网解决方案 资料专区…

怎样的网站打开速度块北京房产网二手房出售

这一部分开始&#xff0c;我们将讲解Python中的组合数据类型&#xff0c;这里的知识十分基础而且重要&#xff0c;也已经与C语言的框架愈差愈远。 目录 序列和索引 1、概念 2、切片操作 3、序列的其他操作 列表 1、概念 2、创建与删除 3、列表的操作 4、列表生成式 …

网站开发 有哪些优化功能4p营销理论

随着电商行业的快速发展&#xff0c;个性化服务已经成为提升用户体验和增加用户粘性的关键。基于API的电商平台数据定制和推荐系统是实现这一目标的重要技术手段。 未来&#xff0c;个性化服务可能会朝以下几个方向发展&#xff1a; 更精准的用户画像&#xff1a;通过API接口…

clickhouse轻量级更新 - 若

轻量级更新(Lightweight Updates)是ClickHouse中的一个重要特性,让我详细解释一下: 什么是轻量级更新 轻量级更新是ClickHouse提供的一种高效的UPDATE机制,它允许在不重写整个数据块的情况下更新数据。 传统更新 …

西电PCB设计指南第3章学习笔记

西电PCB设计指南第3章学习笔记 三、PCB的设计与规范画图前的准备确定外轮廓(在机械层核对尺寸,安装孔位,定义PCB边界轮廓)设置layerstack(节点厚度和属性)话说我好像安装了专门算这个的软件?嘿嘿嘿:happy:那么为…

Vitrualbox、kali、metaspolitable2下载安装

太多资源看不过眼,整理了几个下载比较快、安装教程比较实用的链接。 这里下的是Virtualbox7.2.2和7.2.2版本的扩展包、kali2025.3和metasplotable2,这里直接用的最新的kali和最新稳定版本的Virtualbox版本。 注意下载…

有域名了如何建网站ftp服务器上传不了wordpress

题解&#xff1a; 我发现拉格朗日乘数法真是个好东西。。 我是不会说我数学竞赛求最值都是用这个东西的 由于我不太会打那个符号就用li代表通常偏导数中的lanmuda 。。。 这题里化简一下就可以得到 2 li * ki * ​(vi​−vi′​)* vi^2​1 然后一旦li确定 我们会发现这个三次函…

LazyLLM端到端实战:用RAG+Agent实现自动出题与学习计划的个性化学习助手智能体

1. 为什么做这个学习助手Agent? 最近,我在写一本关于Git和开源的技术书,这本书未来有个推广方向,就是面向高校作为教材使用。所以我需要在每一章结束在之后,设计若干道练习题,然后还需要为这本书编写配套的PPT以…

补充图

最小生成树(K算法和P算法)(1)K 算法(每次找最小边,判断是否存在环)TIPS:使用并查集实现合并、查询等操作。(常数级别),这里暂未使用。(2)P 算法

域名+邮件推送+事件总线=实现每天定时邮件!

需求:十二点之前我就要睡觉了,我希望给自己一个提醒,但是这个提醒不能是闹钟,因为我一旦在闹钟之前睡去,这闹钟反而要一直响个不停了。 根据这个需求,我盯上了自动邮件,发现目前市场上的自动邮件服务都是付费居…

llm入门环境

Jupyter Notebook安装 官网 https://jupyter.org/install 命令安装 $ pip install jupyterlab 启动 $ jupyter-lab Langchain安装 命令 $ pip install langchain$ conda inatall langchain -c conda-forge 也可以使用V…

手机网站 微信分享建设酒店网站ppt模板

ctrl shift P 选择 go install/update tools&#xff0c;下载go tools 报错&#xff0c; 提升dial err。 将GOPROXY 和 GOSUMDB 按照如下配置&#xff0c;重启IDE即可成功下载 set GOPROXYhttps://goproxy.cn set GOSUMDBoff

网站开发排行零基础学jsp网站开发

google浏览器是不能够安装的除非有v*p*n&#xff08;&#xff09; Firefox浏览器可以安装js脚本 推荐使用 1 google 扩展 IDMan628 扩展程序里面加 IDMGCExt.crx 2 扩展Tampermonkey 加Tampermonkey.crx 3 点击Tampermonkey 的仪表盘 右上角加按钮 百度网盘直接下载助手…

2017网站开发工程师php网站后台入口

rocketmq默认就是可以批量消费的&#xff0c;但需要设置多个参数一起配合。 我们只需要知道他是怎么消费的&#xff0c;就可以很精准的设置他的批量消费参数。 我们看看DefaultMQPushConsumer源码中的这几个参数&#xff1a; /*** 消费消息线程&#xff0c;最小数目*/private …

湖南网站建设开发免费做产品宣传的网站

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…