Как понять часть и раздел ClickHouse?

Я вижу, что clickhouse создал несколько каталогов для каждого ключа раздела.

В документации говорится, что формат имени каталога следующий: имя раздела , минимальное количество блоков данных, максимальное количество блоков данных и уровень фрагментов. Например, имя каталога 201901_1_11_1.

Я думаю, это означает, что каталог является частью раздела 201901, имеет блоки от 1 до 11 и находится на уровне 1. Таким образом, у нас может быть другая часть, каталог которой похож на 201901_12_21_1, что означает, что эта часть принадлежит разделу 201901, имеет блоки от 12 до 21 и находится на уровне 1.

Поэтому я думаю, что раздел разбит на разные части. Я прав?


person GOGO    schedule 10.02.2020    source источник
comment
Не - перегородка не разбивается на части, перегородка собирается по частям. Первоначально части создаются с помощью INSERT (поэтому очень важно следовать правилу вставки) и периодически объединяются, чтобы иметь несколько больших частей (в идеале только по одной части на раздел). Посмотрите на это объяснение: github.com/ClickHouse/ClickHouse/issues/   -  person vladimir    schedule 10.02.2020
comment
@vladimir Спасибо за ответ. Согласно вашему ответу, в каталоге частей у нас может быть несколько разделов, и каждый раздел имеет свой собственный каталог в каталоге частей. И когда мы читаем данные, нам нужно проверить каждый диапазон разделов в части, чтобы выбрать, что читать. Я правильно понимаю?   -  person GOGO    schedule 10.02.2020


Ответы (2)


Части - части таблицы, в которой хранятся строки. Одна часть = одна папка с колонками.

Разделы - это виртуальные сущности. У них нет физического представления. Но можно сказать, что эти части принадлежат одному разделу.


Select не заботится о разделах.

Select не знает о ключах разделения.

ПОТОМУ ЧТО каждая часть имеет специальные файлы minmax_ {PARTITIONING_KEY_COLUMN} .idx Эти файлы содержат минимальные и максимальные значения этих столбцов в этой части. Также значения minmax_ хранятся в памяти в виде списка частей (вектор С ++).

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) и этот выбор необходим (555, 555).

CH не хранит значения ключей разделения.

Так, например, toYYYYMM (today ()) = 202002, но этот 202002 не сохраняется ни в части, ни где-либо.

minmax_B.idx магазинов (18302, 18302) (2020-02-10 == select toInt16(today()))

person Denny Crane    schedule 10.02.2020
comment
Я думаю, что индекс minmax - один из индексов пропуска. Я вижу, вы создаете таблицу без указания индекса minmax, а MergeTree создаст индекс minmax по умолчанию? - person GOGO; 14.02.2020
comment
@GOGO вы ошибаетесь. Вот как работает разбиение и удаление разделов. Я обнаружил это и сделал для себя собственное уведомление, используя версию clickHouse 1.1.54394, 2018-07-12, которая была выпущена за 2 года до изобретения индексов пропуска. - person Denny Crane; 14.02.2020
comment
Спасибо. Как вы сказали, одна часть принадлежит одному разделу? И диапазон разделения каждой части записан в имени каталога частей? - person GOGO; 15.02.2020
comment
Раздел @GOGO закодирован в названии детали (названии папки). 1-202002_1_1_0 - 1-202002 - раздел (название). 1_1 - диапазон блоков (1 - просто порядковый номер - идентификатор блока uniq). 0 - уровень (0 вставка - никогда не объединяется) clickhouse.tech/docs/en / operations / table_engines / - person Denny Crane; 15.02.2020
comment
Таблицы, созданные с использованием старых (устаревших) таблиц синтаксиса, имеют другое название части, а имя части (папки) содержит диапазоны дат 20200215_20200215_1_1_0 - person Denny Crane; 15.02.2020

В моем случае я использовал groupArray () и arrayEnumerate () для ранжирования в Populate. Я думал, что Populate может выполнять запрос с новыми данными в разделе (в моем случае: toStartOfDay (Date)), общая сумма новых вставленных данных верна, но функция groupArray () работает некорректно.

Я думаю, это произошло потому, что при вставке одной части CH сразу же groupArray () ранжирует каждую часть, а затем объединяет части в один раздел, поэтому я не получу точно окончательный результат функций groupArray () и arrayEnumerate (). Сводка, слияние

[groupArray (part_1) + groupArray (part_2)] отличается от groupArray (Partition)

с участием

Раздел = часть_1 + часть_2

Решением, которое я пробовал, является вставка новых данных как один размер блока, как при использовании groupArray (), чтобы уменьшить количество новых данных до количества строк, меньшего, чем max_insert_block_size = 1048576. Он сделал правильно, но трудно вставить новые данные за 1 день как одну часть, потому что он будет использовать слишком много памяти для запросов при заполнении данных за 1 день (почти 150–200 млн строк).

Но есть ли у вас другое решение для заполнения с помощью groupArray () для новых вставляемых данных, например, заставить CH использовать POPULATE для каждого раздела, а не для каждой части после объединения всей части в один раздел?

person Dinh Ngoc    schedule 09.03.2020