уникальный id (UID), в течении месяца он может совершить действие (ACTION).
Нюанс что действие (ACTION) совершается в другой системе, от которой мы получаем только id юзера (UID)
Задача найти за месяц баннеры которые были показаны юзерам которые совершили нужное действие.
SELECT ad, uid FROM db WHERE uid IN (SELECT DISTINCT uid FROM db WHERE action='ACTION') работает, но плохо.
В сутки до 50млн хитов, и до 500к хитов с нужными ACTION.
Наверняка у кого-то были схожие задачи. Что можно сделать чтоб избежать фул скан по UID ?
Не уверен, но можно попробовать что-то типа SummingMergeTree + хранить action в массиве. Надо будет аккуратно настроить primary key + order by чтобы парты были адекватного размера. + Все сильно будет зависить от вставки (инсерт по многим uid породит очень много фоновых мержей). У меня такая система система для нескольких дней работала. Но в любом случае селект по строке uid - это не к клику. Я бы сделал этот на стороне а в клике оставил только статку CollapsingMergeTree и обновлял ее раз в N времени P.s. retention был бы проще потому что все action 1 uid хранятся в 1 строке
SummingMergeTree не поможет, потому что по итогу нужны не только кол-во юзеров увидевших баннер, но и конкретные UID (и к примеру время показа банера/время дествия). Единственное, думал UID генерить на основе таймстемпа (вместо рандома).., что теоретически даст подсказку о том, в каком временном диапазоне искать инфу о показе банера. Но как это поможет оптимизировать запрос, и как для этого должна быть структурирована база пока не понимаю.
Ну можно несколько колонок связанных иметь, но это не решает самой проблемы поиска по uid. https://clickhouse.tech/docs/ru/sql-reference/data-types/nested-data-structures/nested/ Плюс можно заполнять время ретеншена для uid из словаря в отдельную колонку, если uid-ов не так много. Но это все велосипеды
а сколько юзеров? select groupArray(ad), uid, countIf(action='ACTION') c group by uid having c>0
>инсерт по многим uid породит очень много фоновых мержей нет
Обсуждают сегодня