есть
У нас есть целевая табличка событий ReplacingMT (~800млн строк)
Там есть колонка id(id юзера), и ts события
И другая AggregationMT, в которой хранится инфа о пользователях, и первый ts для каждого юзера
И запрос, который использует инфу о первом событии пользователя (ну типа появился ли пользователь в этом событии впервые, или уже существовал)
Проблема в том, что для join'a требуется очень много памяти, я выхожу за границы RAM
Есть ли какая-нибудь возможность присоединить к целевой таблице событий инфу о существовании пользователя, не напрягая столь сильно память? И как это сделать?
если у вас FROM a JOIN b ON ... WHERE то замените на подзапросы FROM (SELECT .. FROM a WHERE ...) t1 JOIN (SELECT ... FROM b WHERE ...) t2 ON ... SELECT * надеюсь нет ? если не пролазите по подзапросам то dictGet из словаря LAYOUT(CACHE(...) https://clickhouse.com/docs/en/sql-reference/dictionaries#cache но скорость упадет скорее всего... причем сильно
Спасибо огромное, сейчас покопаюсь, попробую, звучит как то, что должно помочь И да, конкретно в этой задаче легко могу пожертвовать скоростью в пользу стабильности
Зависит от запроса (сколько пользователей за раз запрашивается) но есть новый алгоритм grace_hash он значительно меньше памяти потребляет (в моих тестах на проде вместо 300гб - 40гб удается использовать) и медленее всего в 2-10 раз чем hash.
Сейчас почитаю, спасибо! Всегда по 2 пользователя (то есть в моем случае это 2* 400млн = 800 млн пользователей), но памяти расходуется много - просто при джоинах, как бы ни вертел, вылезаю из ограничений
Простите, не разобрался пока, это задается в контексте запроса строкой SETTINGS join_algorithm=grace_hash ?
Да только в кавычках ' '
Странно - пока не увидел разницы, слег из-за памяти на том же кол-ве прочтенных строк Или неправильно использую...
там можно задавать кол-во ведер я делаю join_algorithm = 'grace_hash', grace_hash_join_initial_buckets=8, grace_hash_join_max_buckets=8
Не могу найти значение по умолчанию - неужели 1 бакет?
select * from system.settings where name like 'grace_hash%'; ┌─name────────────────────────────┬─value─┬─changed─┬─description────────────────────────────────────┬─min──┬─max──┬─readonly─┬─type───┬─default─┬─alias_for─┐ │ grace_hash_join_initial_buckets │ 1 │ 0 │ Initial number of grace hash join buckets │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ 0 │ UInt64 │ 1 │ │ │ grace_hash_join_max_buckets │ 1024 │ 0 │ Limit on the number of grace hash join buckets │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ 0 │ UInt64 │ 1024 │ │ └─────────────────────────────────┴───────┴─────────┴────────────────────────────────────────────────┴──────┴──────┴──────────┴────────┴─────────┴───────────┘ там алгоритм который пытается менять / подобрать кол-во бакетов не очень хорошо работает
Denny, подскажите, пожалуйста, с чем мб связана эта ошибка: Can't execute GRACE_HASH join algorithm for this strictness/kind and right storage type. (NOT_IMPLEMENTED) В джоне участвует табличка ReplacingMT, MT, да и все вроде
join - то какой ? ASOF ANY CROSS ?
Right join (outer же по умолчанию, так?)
так поменяйте местами таблицы и сделайте Left
Не понимаю, как и почему должно помочь, буду рад, если поясните Но попробую, спасибо! Однако, у меня и так сейчас слева таблица сильно больше, чем та что справа, разве не логичнее держать их в таком порядке?
справа таблица не которая спара во from , а та которая справа и логике join
Здравствуйте еще раз! Пытаюсь сейчас разобраться со словарем, подскажите еще пожалуйста Создал его как вы указали, но при попытке к нему обратиться я получаю ошибку авторизации: Authentication failed: password is incorrect, or there is no user with such name (хотя естесственно, в остальных запрос такого нет) То есть сохранить словарь надо как-то по-особенному, или в любом случае нужно передавать через запрос параметры user/pw? И если так, то как это сделать?
SHOW CREATE TABLE db.dictionary_name FORMAT Vertical; покажите без паролей
CREATE DICTIONARY item_dict ( id UInt64, attr String ) PRIMARY KEY id SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 TABLE item_dict_t DB 'dw' USER 'myuser' PASSWORD 'mypassword' )) LIFETIME(MIN 0 MAX 0) LAYOUT(HASHED());
простите, что это за таблица? Просто копипаст дал, что нет такой таблицы
Спасибо большое - попробую! А при общении со словарями если удаленно всегда так? Это в настройках сервера надо колдовать?
ну словарь всегда использует пользователь/пароль аунтефикацию непонятно в чем вопрос. можно ли опустить пользователь/пароль ? Можно, если они дефолтные можно ли описать пару пользователь/пароль по другому чтобы не писать их в CREATE DICTIONARY? можно - named collections
вы словарь сделали как ? через CREATE DICTIONARY или через XML?
ну, а имя словаря то помните и в какой базе создавали?? ну вот SHOW CREATE TABLE имя_базы.имя_словаря FORMAT Vertical покажите только пароль на XXX замените если он там в SOURCE есть
Да, точно, извиняюсь Не указывал при создании В этом дело?
сколько записей в adresses таблице? SELECT count() FROM default.addresses ? на сервер доступ по ssh есть? SELECT address, frist_transaction FROM remote('localhost:9000',default.addresses) FINAL работает? или тоже ошибку выдает? и шарь инфу ТЕКСТОМ, шаринг картинками текстовой инфы, это признаваться что ты не половозрелый подросток и в CTRL+C / CTRL+V не умеешь
https://t.me/clickhouse_ru/329219
Записей безумно много - 1млрд По ssh есть доступ, второй запрос отрабатывает Окей, буду текстом шарить, не вопрос)
https://clickhouse.com/docs/en/operations/named-collections#ddl-example https://clickhouse.com/docs/en/operations/named-collections#example-of-using-named-collections-with-a-dictionary-with-source-clickhouse SOURCE(CLICKHOUSE(NAME ... QUERY '...'))
вместо query сделай CREATE VIEW default.addresses_view AS SELECT address, first_transaction FROM default.addresses FINAL и вместо QUERY указывай обычную DB и TABLE
Сделал Но пока получаю ошибку по прошествии 10 сек запроса SQL Error [1000] [08000]: Poco::Exception. Code: 1000, e.code() = 0, Not found: dictionary.layout.cache.size_in_cells Проверю создание
ну как бы доку надо почитать про LAYOUT(CACHE()) https://clickhouse.com/docs/en/sql-reference/dictionaries#cache
Обсуждают сегодня