строк в день. Нужно сделать относительно быстрые выборки детализации по периоду и полям msisdna, mssisdnb, imeia, imeib bsa, bsb. При этом период может быть от дня до года. В результате будет отбираться 100-200 тыс записей. Эти поля - идентификаторы абонентов никак не упорядоченные на периодах и индексы помогают плохо. Есть ли возможность как-то ускорить выборки по не локализованным данным (упорядоченно только по времени) индексировать/добавить материализованных вьюх?
В пределах дня все выбирается шустро, но вот на больших периодах хотелось бы побыстрее...
CREATE TABLE calls(
call_id Int64,
start_time DateTime,
msisdna String,
mssisdnb String,
imeia String,
imeib String,
bsa String,
bsb String
...
куча полей с детализацией
...
ENGINE = ReplicatedMergeTree(...)
PARTITION BY (toStartOfMonth(start_time))
ORDER BY (toDate(start_time))
Спасибо
можете попробовать создать проекцию с нужной вам сортировкой или группировкой. Если версия старая то через materialized view
А у вас на месячных партициях нормально мерджи проходят?
а сколько всего абонентов в базе? т.е. сколько записей будет в этих вьюхах?
Пока только один месяц тестировал - нормально
Порядка 100 млн в одном из срезов. В каких-то срезах побольше.
т.е. за 365 дней в таблице будет 10-30 миллиардов записей? и насколько оперативно вы хотите эти данные обновлять - раз в сутки?
ну я предполагаю что во вьюхах будет необходимая сортировка, а по количеству записей она будет совпадать с основной таблицей. В основную льется непрерывно пачками по 100 тыс записей примерно. Запросов в течении дня будет не много, обычно на пероде несколько недель. Никогда не использовал вьюхи на больших таблицах и нет уверенности в правильности такого подхода.
как я понял, вы даже сгруппировать по дням не можете. чисто физически, такая сортировка, если вас устроит обновление раз в день, должна выглядеть как сортировка новых записей за день + слияние новой таблицы со старой. повторить для каждого поля, котрое вам нужно как ключевое
а быстро-медленно - это сколько в секундах?
Запросы за месяц во всех разрезах хотелось бы уложить в 20-30 сек. За несколько месяцев чтобы линейно увеличивалось
Спасибо. Вы говорите про дополнительные таблицы или мат. вьюхи?
я не разбираюсь в CH. так что говорю о том, как оно в лучшем случае "физически" может быть реализовано
Нельзя ли сделать основную сортировку по одному из полей, которые используются в запросе? Например, по msisdna? Если да, то, возможно, еще есть смысл поэкспериментровать с размером партиции, сделав их поменьше. Запросам по году это не поможет, а по дню - вполне. Если нет, попробуйте посмотреть в сторону skip indexes https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#table_engine-mergetree-data_skipping-indexes
Спасибо, как раз с ними сейчас эксперементирую. Да, одно поле засунул в сортировку, т к по нему запросы чаще. На остальные пробую скип индексы. Планирую баловаится с гранулярностью
во-первых, таких полей несколько. условно кто звонили и кому звонили. во-вторых, каждый день к КАЖДОМУ номеру будет добавляться несколько строк данных. тут минимум b-дерево нужно, но оно вряд ли выдержит такой объём работы. моя идея с сортировкой+слиянием куда дешевле, если так можно сделать в CH
конечно хотелось бы аггрегировать, но человеку нужны выборки. так что нет - полный x7 и никаких аггрегаций :(
Ежу понятно order by надо переделать
а как его переделать если он хочет и по времени, и ещё по 6 полям? И все независимо друг от друга?
Вообще не проблема
Важно засунуть на правильное место, а именно первым. А второе по частоте использования поле хорошо бы засунуть вторым. При этом timestamp из индекса убрать, сделав партиции по дням. Про усемерение данных вам правильно советовали, только не обязательно прямо усемерять, может быть достаточно удвоить (т.е. хранить все данные в двух таблицах с двумя сортировками). Ну а остальные (более редкие) запросы как-нибудь так, полным перебором. Или, при удаче, со skip индексами.
если хранить данные в физическом порядке (по дням), то каждый запрос превращается в 100к random reads. а уж полный перебор по триллиону записей - это вообще шутка дня
Вы что-то не то говорите.
Может хранить во вспомогательной таблице (таблицах) id звонка, даты и поле отсортированное по которому ищем. Т к в результате относительно мало записей будет. Ну и выбирать из основной таблицы по полученным id звонков?
Это довольно сильно противоречит идеологии ClickHouse (в отличии от предложения дублировать все данные). Но никто не может вам запретить действовать именно так ;)
сортировка в основной таблице будет по id звонка, много партов будет пропускаться
дело в том что данные с диска читаются порциями по 4 КБ. добавьте ещё что они хранятся поколоночно. как тут предложили, индекс будет с дискретностью 256 строк (больше всё равно в озу не влезет) так что всё равно вы будете читать по 4 КБ / 256 записей за раз, и что так что этак у вас будет 100 тыщ таких партов если 100 тыщ строк в результате запроса
Обсуждают сегодня