如何理解clickhouse的部分和分区?

hiz5n14c  于 2021-07-15  发布在  ClickHouse
关注(0)|答案(2)|浏览(463)

我看到clickhouse为每个分区键创建了多个目录。
文档中说目录名的格式是:分区名、最小数据块数、最大数据块数和块级别。例如,目录名为 201901_1_11_1 .
我认为这意味着目录是属于分区201901的一部分,它的块从1到11,并且在级别1上。所以我们可以有另一个目录是 201901_12_21_1 ,这意味着该部分属于分区201901,具有从12到21的块,并且在级别1上。
所以我认为分区被分成不同的部分。我说得对吗?

k7fdbhmy

k7fdbhmy1#

部分——表中存储行的部分。一部分=一个带列的文件夹。
分区是虚拟实体。它们没有物理表征。但是你可以说这些部分属于同一个分区。
选择不关心分区。
select不知道分区键。
因为每个部分都有特殊的文件minmax{partitioning\u key\u column}.idx,所以这些文件包含这个部分中这些列的最小值和最大值。此外,这个minmax值存储在内存中的(c++向量)部件列表中。

create table X (A Int64, B Date, K Int64,C String) 
Engine=MergeTree partition by (A, toYYYYMM(B)) order by K;

insert into X values (1, today(), 1, '1');

cd /var/lib/clickhouse/data/default/X/1-202002_1_1_0/
ls -1 *.idx
minmax_A.idx   <-----
minmax_B.idx   <-----
primary.idx

SET send_logs_level = 'debug';
select * from X where A = 555;

(SelectExecutor): MinMax index condition: (column 0 in [555, 555])
(SelectExecutor): Selected 0 parts by date

selectexecutor签入内存部件列表并找到0个部件,因为minmax_a.idx=(1,1)并且需要此select(555,555)。
ch不存储分区键值。
例如toyyyymm(today())=202002,但是这个202002不存储在零件或任何地方。
minmaxèb.idx商店(18302、18302) (2020-02-10 == select toInt16(today()))

km0tfn4u

km0tfn4u2#

在我的例子中,我使用了grouparray()和arrayenumerate()在populate中进行排名。我认为populate可以使用分区上的新数据运行查询(在我的示例中为:tostartofday(date)),新插入的数据的总和是正确的,但是grouparray()函数不能正常工作。
我认为这是因为当插入一个部分时,ch会立即对每个部分进行grouparray()和rank,然后将部分合并到一个分区中,因此我无法得到grouparray()和arrayenumerate()函数的最终结果。摘要,合并
[grouparray(part\ 1)+grouparray(part\ 2)]与grouparray(partition)不同

分区=第1部分+第2部分
我尝试的解决方案是将新数据作为一个块大小插入,就像使用grouparray()将新数据的行数减少到小于max\u insert\u block\u size=1048576的行数一样。它确实正确,但很难将1天的新数据作为一部分插入,因为在填充1天的数据(几乎是150mn-200mn行)时,它将使用太多的内存进行查询。
但是你有没有另一个解决方案来用grouparray()填充新的插入数据,比如强制ch在每个分区上使用populate,而不是在将所有部分合并到一个分区后在每个部分上使用populate?

相关问题