184 похожих чатов

Здравствуйте) Планируем собирать метрики с 2 разных сущностей, и чтобы построить

общую воронку, эти метрики нужно как-то соединять
Проблема в том, что соединение этих сущностей многие-ко-многим, что порождает 2 джойна больших таблиц (каждая прирастает на овер 16 млн строк в сутки) через таблицу с маппингом (всего около 20тыс строк, прирастает медленно)

Соответственно, чтобы соединить данные нужно выполнить следующее: джойн 1 большой таблицы с маппингом -> получаем большую таблицу, (вариативно)группировка результата, джойн 2 большой таблицы

Сейчас в кликхаусе получше обстоят дела с джойнами (появился джойн для больших таблиц, джойн во внешней памяти), но все равно скрипты будут получаться достаточно громоздкими (нельзя использовать несколько джойнов подряд и нужно уходить в подзапросы)и из-за большого размера таблиц растет риск уронить запрос по памяти

Возможно кто-то уже сталкивался с подобной проблемой?

Мы также рассматривали возможность скидывать метрики с обеих сущностей в одну супер-большую таблицу, но тогда неочень понятно как их соединять: 2 подзапроса опять же породят 2 таблицы из одной, которые затем соединятся через таблицу с маппингом через 2 джойна. Кроме того мы чаще работаем с данными каждой сущности по отдельности, соответственно нужно будет добавлять специальное поле, чтобы иметь возможность быстро фильтроваться по метрикам. Также структура метрик у этих сущностей имеет существенные различия, поэтому будут полупустые колонки, заполненные значениями только для какой-то одной сущности

13 ответов

4 просмотра

Вариант с супер широкой таблицей выглядит радужнее. Пропуски в метриках? - ну и ладно. Можно попробовать уложить метрики в словари. Широкую табличку можно сделать через MV

join не нужен. На самом деле вы клеите все ивенты по какому-то id в одну строку, это group by а не join поэтому масса вариантов, grouparray , WF маппинг в словарь и мапить лучше в момент инсерта

Katherine-K Автор вопроса
Denny [Altinity]
join не нужен. На самом деле вы клеите все ивенты ...

У нас есть UserId, но этих пользователей нужно потом раскидывать по кучкам (b2b2c модель), соответственно тех людей, которые с 0 шага перешли на первый мы без проблем таким образом распределим по нашим провайдерам (основная сущность), но вот чтобы посчитать конверсию нулевого шага, где у нас другая сущность (профиль) возникают проблемы

Katherine K
У нас есть UserId, но этих пользователей нужно пот...

ну вы наизобретали разных терминов, которые у вас там используются (профиль, шаг0, пользователь, провайдер) это все шелуха. Абстрактно мы все тут в этом чате решаем одну и туже задачу, клеим кучи ивентов в строку и обсчитываем воронки, и не нужны джойны, просто вам надо осознать задачу под другим углом

Katherine K
У нас есть UserId, но этих пользователей нужно пот...

У нас тоже b2b2c. Вы наверное задачу в терминах реляционных баз представляете. А вам нужно ее как огромную таблицу фактов с приклеенными атрибутами

Katherine-K Автор вопроса
Denny [Altinity]
ну вы наизобретали разных терминов, которые у вас ...

это технические ограничения системы, уже есть профиль, уже есть провайдер (система живет больше 10 лет) соответственно наши аналитики не могут сказать, сносите все и пилите заново с одной сущностью, а пытаются каким-то образом подстроить аналитическую систему

извините, но так на вскидку кажется что нужно нормально написать запросы и посмотреть на структуры данных 16млн в день это не так чтобы овер много. ну и посмотреть на типы данных. может нужно закастовать в лоукардиналит и инты (в том числе внутри мапов и эрреев) далее если всё равно много вычислений то можно написать материлизацию со сплитами (чтобы по памяти не падало) я так думаю сделать для сложных маркетинговых расчетов. но так и не доьрался так как каждый раз нахожу способы ускорить через нормальное написание запросов. подзапросы вообще зло. из-за них код хрен поймешь. используйте with / cte по гайдланам гитлаба

Anttoon
А что за гайдлайны? Как найти?

одна операция в одном алиасе. то есть пишите вверху оди with и дальше каждое вычисление отдельным блоком. все джойны желательно через using вообще если перфекционизмом заниматся:) https://gitlab.com/gitlab-data/analytics/-/blob/master/transform/snowflake-dbt/models/marts/pumps/subscription_product_usage_data.sql ну я вот так пишу, просто рандомная моделька кусок

William Ko
screenshot одна операция в одном алиасе. то есть пишите вверх...

Выглядит - офигенно. Но вот всмысле читать - не очень удобно как по мне

Oleg
Выглядит - офигенно. Но вот всмысле читать - не оч...

да не. читать 100% удобнее, просто непривычно ну и разные стили по отступам может вам другой комфортнее. тут самое важное это простота отладки. в конце модели всегда делается select * from last_cte и можно подставить любой промежуточный шаг и посмотреть.

Похожие вопросы

Обсуждают сегодня

И ещё вопрос: можно ли типа как на дос как-то запариться и с помощью прерываний выводить текст, вместо функции printf ?
НѣкъиⰘижєжєиꙁъвьсєсвѣтьноѣсѣтиѥсть•
34
Ладно, ещё тупого спрошу. Код должен банально вывести значение регистра на консоль, на деле же не выводя ничего, просто оставляя нерабочую консоль (открыта, ничего не написан...
НѣкъиⰘижєжєиꙁъвьсєсвѣтьноѣсѣтиѥсть•
25
здравствуйте. пытаюсь проверить, содержится ли в десятичном представлении инта некоторая цифра. совершаю: strstr(x, "5") != NULL) получаю ошибку с фото (заведомо неработающий ...
Катя Шевчук🪇
17
Что там вообще с кроссплатформенностью?
🄼🄰🄺🅉🄰🄸
23
{ char buff = *start; *start = *end; *end = buff; } Из-за этой строчки? Что каждый символ через перем бафф? Как вариант использовать другие со...
Wenks
12
#include <stdio.h> #include <string.h> int main() { char *str = "Hello World"; char *ptr; int i = 0; for(char *end = str + strlen(str) - 1; end = str; ptr++, ...
Wenks
9
а я правильно понимаю что в винде сетевые диски выполнены на уровне юзерспейс драйвера? ну я про те которые webDAV, SMB и прочие высокоуровневые
Mixail Frolov
9
Доброй ночи. Вопрос знатокам. Имеется некая таблица, результат которой выведен в DBGrid на форме. И есть форма, с помощью которой можно как добавить запись, так и отредактиров...
Евгений
28
Кстати, а я вот тут подумал. Допустим, у нас имеется цикл который выполняет огромное количество итераций, но мы хотим, чтобы какие-то действия исполнилось только один раз. В Я...
The Bird of Hermes
23
а всё почему? потому что ассемблер в отличии от яву порождает множество пагубных привычек, среди которых например можно отметить использование глобальных переменных для всего ...
Mixail Frolov
35
Карта сайта