clickhouse - 如何理解 ClickHouse 中的粒度和块?
问题描述
这两个词我不是很清楚。一个块是否有固定的行数?一个块是否是从磁盘读取的最小单位?不同的块是否存储在不同的文件中?一个块的范围是否大于颗粒?这意味着,一个块可以有多个颗粒跳过索引。
解决方案
主键是稀疏的。默认情况下,它包含每 8192 行中的 1 个值(= 1 个颗粒)。
让我们禁用自适应粒度(用于测试)-- index_granularity_bytes=0
create table X (A Int64)
Engine=MergeTree order by A
settings index_granularity=16,index_granularity_bytes=0;
insert into X select * from numbers(32);
index_granularity=16 -- 32 行 = 2 个粒度,主索引有 2 个值 0 和 16
select marks, primary_key_bytes_in_memory from system.parts where table = 'X';
┌─marks─┬─primary_key_bytes_in_memory─┐
│ 2 │ 16 │
└───────┴─────────────────────────────┘
16 个字节 === INT64 的 2 个值。
自适应索引粒度意味着粒度大小不同。因为宽行(很多字节)需要(为了性能)更少的(<8192)行。
index_granularity_bytes = 10MB ~ 1k row * 8129. 所以每个颗粒有 10MB。如果行大小为 100k(长字符串),则颗粒将有 100 行(不是 8192)。
Skip index granules GRANULARITY 3 - 表示索引将为每 3 个表颗粒存储一个值。
create table X (A Int64, B Int64, INDEX IX1 (B) TYPE minmax GRANULARITY 4)
Engine=MergeTree order by A
settings index_granularity=16,index_granularity_bytes=0;
insert into X select number, number from numbers(128);
128/16 = 8,表有 8 个颗粒,INDEX IX1 存储 2 个 minmax (8/4) 值
所以 minmax 索引存储 2 个值 - (0..63) 和 (64..128)
0..63 -- 指向前 4 个表的颗粒。
64..128 -- 指向第二个 4 table' 颗粒。
set send_logs_level='debug'
select * from X where B=77
[ 84 ] <Debug> dw.X (SelectExecutor): **Index `IX1` has dropped 1 granules**
[ 84 ] <Debug> dw.X (SelectExecutor): Selected 1 parts by date, 1 parts by key, **4 marks** to read from 1 ranges
SelectExecutor 检查跳过索引 - 可以跳过 4 个表颗粒,因为 77 不在 0..63 中。并且必须读取另外 4 个颗粒(4 个标记),因为 77 in (64..128) - 其中一些 4 个颗粒的 B=77。
推荐阅读
- r - 在 R Studio 中创建列
- c++ - 为什么我可以在 C++ 中从文件中读取 int 值但不能浮动?
- c# - 连接两个套接字的问题
- python - 如何在 python 中将此字符串值转换为日期?
- html - Toggle Div Style Between Opened (Display: Block) and Closed (Display: None) With jQuery
- python - 带有 python 的 Openvino 返回一些错误
- arrays - 如何在 Swift 中查找匹配数组元素的所有索引
- angular - Rxjs 组合对象(正确的方式)
- python-3.x - 在 Atom 中使用氢设置 Python 虚拟环境
- c# - 在 C# Visual Studio 中计算二维数组中整数的出现次数