我看到clickhouse为每个分区键创建了多个目录。
文档中说目录名的格式是:分区名、最小数据块数、最大数据块数和块级别。例如,目录名为 201901_1_11_1
.
我认为这意味着目录是属于分区201901的一部分,它的块从1到11,并且在级别1上。所以我们可以有另一个目录是 201901_12_21_1
,这意味着该部分属于分区201901,具有从12到21的块,并且在级别1上。
所以我认为分区被分成不同的部分。我说得对吗?
我看到clickhouse为每个分区键创建了多个目录。
文档中说目录名的格式是:分区名、最小数据块数、最大数据块数和块级别。例如,目录名为 201901_1_11_1
.
我认为这意味着目录是属于分区201901的一部分,它的块从1到11,并且在级别1上。所以我们可以有另一个目录是 201901_12_21_1
,这意味着该部分属于分区201901,具有从12到21的块,并且在级别1上。
所以我认为分区被分成不同的部分。我说得对吗?
2条答案
按热度按时间k7fdbhmy1#
部分——表中存储行的部分。一部分=一个带列的文件夹。
分区是虚拟实体。它们没有物理表征。但是你可以说这些部分属于同一个分区。
选择不关心分区。
select不知道分区键。
因为每个部分都有特殊的文件minmax{partitioning\u key\u column}.idx,所以这些文件包含这个部分中这些列的最小值和最大值。此外,这个minmax值存储在内存中的(c++向量)部件列表中。
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()))
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?