id String,
clicked_date Date DEFAULT toDate(clicked_at),
clicked_at DateTime('UTC'),
campaign_id UUID,
domain_id SimpleAggregateFunction(anyLast, Nullable(UUID)),
referrer SimpleAggregateFunction(anyLast, Nullable(String)),
country SimpleAggregateFunction(anyLast, Nullable(String)),
device SimpleAggregateFunction(anyLast, Nullable(String)),
os SimpleAggregateFunction(anyLast, Nullable(String)),
cost SimpleAggregateFunction(anyLast, Nullable(Float32)),
isVisited SimpleAggregateFunction(anyLast, Nullable(UInt8)),
isTargeted SimpleAggregateFunction(anyLast, Nullable(UInt8)),
meta_value_1 SimpleAggregateFunction(anyLast, Nullable (Decimal(15,8))),
meta_value_2 SimpleAggregateFunction(anyLast, Nullable (Decimal(15,8))),
meta_value_3 SimpleAggregateFunction(anyLast, Nullable (Decimal(15,8)))
)
ENGINE = AggregatingMergeTree
PARTITION BY toYYYYMM(clicked_at)
PRIMARY KEY (id, clicked_date, campaign_id)
ORDER BY (id, clicked_date, campaign_id);
Есть 3 разных набора данных привязанный к id, 3 типа событий происходят в разное время, для примера 30к данных
1. Все колонки (10к)
2. id, clicked_at, campaign_id, cost, isVisited, meta_value_1, meta_value_2, meta_value_3 (10к)
3. id, clicked_at, campaign_id, isTargeted, meta_value_1, meta_value_2, meta_value_3 (10к)
как оптимально вставлять данные? Варианты
- Вставлять все наборы разом приводя к единой схеме и сразу 30к
INSERT INTO clicks (id, clicked_at, campaign_id, domain_id, referrer, country, device, os, cost, isVisited, isTargeted, meta_value_1, meta_value_2, meta_value_3)
VALUES ('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', '22000000-0000-0000-0000-000000000022','http://example.com', 'Russia', 'nokia', 'windows', null, 0, 0, 0, 10, 0)
('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', null, null, null, null, null, 10, 1, 0, null, null, 20)
('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', null, null, null, null, null, null, null, 1, null, null, null)
- Вставлять каждый набор по отдельности по 10к?
INSERT INTO clicks (id, clicked_at, campaign_id, domain_id, referrer, country, device, os, cost, isVisited, isTargeted, meta_value_1, meta_value_2, meta_value_3)
VALUES ('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', '22000000-0000-0000-0000-000000000022','http://example.com', 'Russia', 'nokia', 'windows', null, 0, 0, 0, 10, 0)
INSERT INTO clicks (id, clicked_at, campaign_id, cost, isVisited, meta_value_1, meta_value_2, meta_value_3)
VALUES ('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', 10, 1, null, null, 20);
INSERT INTO clicks (id, clicked_at, campaign_id, isTargeted, meta_value_1, meta_value_2, meta_value_3)
VALUES ('c6f06ktmk1u7lohuee00', now(), '11000000-0000-0000-0000-000000000011', 1, null, null, null)
можно вставлять через mat.view и оно схлопнет в select который вы напишете. INSERT INTO clicks VALUES ( .... now() ) любая функция в секции VALUES выключает stream parser и включает AST парсер, что резко ограничивает возможный размер инсерта (до 256кб) и увеличивает потребление памяти и cpu. Лучше это делать в select в mat.view или задавать default now() в поле.
лучше вставлять одним инсертом
Но я скорее не про агрегированную промежуточную таблицу, а raw таблицу Хочу иметь одну таблицу в которой храняться все события как они были, а уже по ней строить агрегации в зависимости от полей и полезных сущностей типа campaign и других Про функцию спасибо👍
максимально гибко - JSONEachRow, тогда хоть 50 наборов
А я правильно понимаю что задается полная схема таблицы, но внутри вот эти разные наборы сами разбираются?
при инсерте схема не задаётся. название колонок и соответсвующие им значения идут в жсонах. у меня 300 колонок, вставляется бесчисленное количество их комбинаций. все схемы на все случаи жизни не описать.
"INSERT INTO $table FORMAT JSONEachRow\n$rows"
Пойду смотреть как это через golang driver сделать, чтобы батчами вставлять
Спасибо, буду изучать
Спасибо, нашел баг, но не уверен что связан с CH, скорее с драйвером go, при вставке в одном батче записей с одинаковым id, мержатся сразу все в одну запись, но с не полными данными
смотрите настройку clickhouse optimize_on_insert
Спасибо, работает, потестирую еще
Вы можете использовать формат при вставки JSOMEachRow и тогда вам не придется приводить к одному виду.
эта фича делает ровно тоже самое при инсерте что и мержи, у вас неправильный order by у таблицы
Я насколько правильно понял что order by в AggregatingMergeTree, это уникальный ключ по которому дедупликация происходит, вот я вижу что весь order by совпадает в двух кликах, почему он не правильный? Если этот флаг делает то же самое, почему тогда с включенным работае правильно? И еще такой ньюанс если вставлять в разных батчах уникальные ключи, все тоже работает правильно
AggregatingMergeTree да схлапывает записи по orderby вы делаете два разных инсерта и вставляете по одной записи с одним значением ключа, мерж позже схлопнет эти две записи в одну если сделать один инсерт и вставить 2 записи сразу, то они прямо инсертом схлопнутся в одну, этот параметр просто позволяет переключать, делать схлапывание в инсерте или нет. И этот параметр жутко замедляет инсерты.
Обсуждают сегодня