Comments 11
Посмотрев на код запросов, у меня сложилось впечатление что их автор умеет в Sql но плохо знает Clickhouse.
Оставлю Вам эту ссылку - https://clickhouse.com/docs/ru/sql-reference/aggregate-functions/reference/argmax
CollapsingMergeTree ( https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/collapsingmergetree/ )не помог бы решить задачу?
Вы запускали это под нагрузкой? У меня никогда не получалось делать тяжелые join в рамках MV, инициированные Kafka Engine. В конечном счете шли ошибки и все останавливалось. Пришлось сделать внешний планировщик, который запускал insert select
Нагрузочное тестирование проводили. Конечно, если в таблицах будет много записей, порядка 1 млрд., вставка больших пачек, скажем 1 млн., будет занимать минуты. И всё будет зависеть от того, устраивает Вас это или нет. У нас не так много новых записей, в сутки до 10 млн., поэтому join-ы не такие тяжёлые, потому что join будет с таблицей в которое количество записей такое, какую пачку выбрал консюмер из Kafka. К тому же сортировку в таблицах мы подбирали так, чтобы join-ы выполнялись как можно более быстро. Разница в скорости в итоге от первого варианта до итогового была ощутимая, если правильно помню около 1.5 раз.
В любом случае как общий подход наше решение советовать не стану, нужно исходить из Ваших конкретных условий. Нагрузка, железо и прочее.
select metrics_dirty.RecId,
metrics_dirty.Time,
metrics_dirty.Sign,
row_number() over(partition by metrics_dirty.RecId,
metrics_dirty.Sign
order by metrics_dirty.Time desc) as rn
from metrics_dirty –-Таблица-источник с грязными данными
left join metrics_uniq –-Таблица-приёмник с уникальными записями
on metrics_uniq.RecId = metrics_dirty.RecId
and metrics_uniq.Sign = metrics_dirty.Sign
where coalesce(metrics_uniq.RecId, '') = '' –-Добавляем, если ещё нет в приёмнике
Вот ваш джойн. Тут правая таблица, которая полезет в память это metrics_uniq, которая большая. Блок вставки - это metrics_dirty, она маленькая, но это уже неважно. Такой join не должен работать в рамках kafka loop processing
Вы, возможно, не обратили внимание на мою оговорку в статье насчёт тяжёлых join, я этот момент затронул. Выходом для нас стало использование with (хотя можно из без него). То что вы говорите верно, если не учесть этот момент, и мы его учли, за счёт чего join для нас стал приемлемым.
Не обратил. Да, так можно. В весьма ограниченных рамках, при низкой интенсивности потока данных.
И очень странно сформулировано (почему with, а не подзапрос?). Очень странно что нет примера на SQL, а приведен неправильный код, который по сути не работает. Вы бы дописали в статью финальную версию.
У нас много полей, c with получался более лаконичный код, но можно и без него, конечно.
Про неправильный код Вы зря, всё таки схема рабочая, а про with и особенность join я упомянул, не захотел писать только чтоб статью сильно не раздувать деталями, хотя может Вы и правы, стоило.
with прекрасен, его надо использовать и даже больше чем у вас в коде. Я про другое. Тот трюк про который вы упомянули (и не описали). Называется подзапрос. with, а более правильнее CTE - это понятие синтаксиса SQL, а не сути того что вы делаете.
Что касается схемы - нет, она нерабочая. Так делать нельзя. Нельзя в рамках kafka loop в общем случае делать такие джойны. Если хотите так сделать - указывайте настройки Kafka Engine, где вы исскуственно ограничиваете размер блока и расширяете временной интервал, так чтобы у вас все работало.
Но я бы так не делал никогда. Вы закладываете мину замедленного действия. Рано или поздно у заказчика увеличится поток данных или просто кафка остановится на сутки, и вы огребете поток, который не сможете отработать должным образом.
Если эта тема вам интереса, то вот мой вариант как это надо делать - https://github.com/bvt123/SCH
Я оторвал кусок от реального проекта и выложил в opensource. И даже что-то описал. Но пока идет тяжело. Если интересно - читайте и задавайте вопросы, может быть это меня простимулирует дописать статью для хабра. А то пока есть ощущение, что это все никому не нужно.
Обновить данные в ClickHouse без UPDATE: кейс IBS