(id String, value String) order by id,
в таблице около 50 миллиардов строк, все ключи и значения уникальны,
есть запрос small_query, который выдаёт около 1 миллиона строк с уникальными value,
если написать запрос вида
insert into new_table select id, value from big_table where value in (select value from small_query)
то естественно имеем full scan всей большой таблицы, который занимает неприличное время
как лучше организовать таблицы (ключи, индексы, что-то еще) чтобы такие запросы выполнялись более эффективно?
таблица на два поля и оба String у вас архитектор системы точно трезвый?
поправка - id - FixedString(16) :)
Этим данным точно место в кликхаус?
данные точно нужны, и используются именно в качестве преобразования вида value —> id
вопрос не "нужны ли данные" вопрос - "точно ли для них подходит кликхаус" если нужно только преобразование, то даже Redis смотрится более подходящим
вот тут уже сложнее, система для меня новая, еще не всё понятно, архитектуру менять задачи не было, пока пытаюсь реализовать выборку за приемлемое время есть входной поток данных - во входном потоке приходят значения value, а таблица на 60 миллиардов выполняет роль справочника, чтобы обогатить входной поток ключами, потом по этим ключам к входным данным будет прикрепляться другая полезная информация
ну как вариант проекция в которой другой ORDER BY value задан... или SkipIndex но насколько это будет эффективнее full scan непонятно сильно завистит от того по скольким партам ваш этот уникальный миллион размазан...
точно никто не мерял, но условно считаем, что 1 миллион размазан по большой таблице равномерно, про партиции да, косяк, сразу не написал - они есть и их уже больше 3800 штук
и какой у вас PARTITION BY ?
ну и вот смотрите у вас есть колонка... value она упакована... поскольку это FixedString(16) предположу, что у вас таблица создана во времена когда не было UUID и это UUID который скорее всего не UUIDv8 который может быть монотонно возврастающим... а обычный UUIDv4 skip indexes тут врятли помогут, потому что они скорее всего будет говорить что в данном парте данные скорее всего есть и парт все равно придется читать... проекция с другим order by может быть поможет но данных на диске станет в два раза больше... и ее еще MATERIALIZE сделать надо для старых данных...
да, всё так - оба поля это практически UUID'ы, только немного оригинальные, поэтому хранятся в виде простых строк, ок, пойду читать про проекции, спасибо за наводку!
ну протестируйте сначала на одном миллионе сабсет... дальше будет понятно работает это или нет...
даже на 100 миллионах запрос выполняется за 0.6 секунды, проблемы начинаются именно на полной таблице :)
проблемы это в смысле "6 секунд"? или что?
или на 100 миллиона там 100 000 value уникальных?
проблемы - это за 20-30 минут прочитано 10% от планируемого числа строк и ничего никуда не вставлено,
ну вы на select + limit попробуйте потренироваться.... без insert
100 миллионов это тестовый кусок от 60 миллиардов, остальные данные не менялись - то есть 1 миллион остался как есть
select ... limit 200 выполняется за 10 секунд, но об общей картине ничего не говорит
более того, относительно недавно выполнялся полный запрос, но видимо нагрузка на сервер возросла или объемы увеличились и всё поплыло
Обсуждают сегодня