uid FROM table ORDER BY time DESC LIMIT 10 BY id
приводит к DB::Exception: Memory limit (total) exceeded.
SHOW CREATE TABLE table FORMAT Vertical текстом расшарьте
там 2летнее легаси. в кратце выглядит так: CREATE TABLE utm ( 'time' DateTime('GMT') CODEC(DoubleDelta, ZSTD(1)), 'id' UInt64 CODEC(ZSTD(1)), 'uid' UInt64 CODEC(ZSTD(1)), 'utm' String CODEC(ZSTD(1)), 'utm_partner' String CODEC(ZSTD(1)), ) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(time) ORDER BY (id,utm) SETTINGS index_granularity = 8192
сколько строк в таблице?
8ярдов. на серваке 64гига памяти... и всё равно не хватает ((
ORDER BY неудачный... в создании таблицы для этого запроса... пересортировку приходится делать... попробуйте SELECT ... SETTINGS max_bytes_before_external_sort=5000000000 но запрос может сильно замедлиться... если не поможет и есть место на диске то попробуйте сделать projection https://clickhouse.com/docs/en/sql-reference/statements/alter/projection#add-projection ALTER TABLE utm ADD PROJECTION last_10_uid ( SELECT id, uid FROM table ORDER BY time DESC LIMIT 10 BY id ) после этого ALTER TABLE utm MATERIALIZE PROJECTION last_10_uid доку по тому что такое projections , очень внимательно прочите чтобы понять что такое проекции https://clickhouse.com/docs/en/optimize/sparse-primary-indexes#option-3-projections
Спасибо. max_bytes_before_external_sort не спасает. Версия КХ 20.12.4, то есть проекций нет. Свободного места на диске 6% осталось... Теоретически думал что для каждого id можно получить время записи последнего uid через argMax. Но что с этим дальше делать придумать не могу, так как нужно получить не 1 uid, а несколько последних (т.е. надо просматривать записи за предыдущие Х дней от даты последней записи). С другой стороны Х - максимум 30 дней... Но всё равно не могу сообразить как это можно использовать.
по моему в 20.12 даже оконок нет... ну требуйте памяти 256 ... ну или апгрейд версии до 22.8 хотя бы...
оконные вроде есть. апгрейд запланирован, но в следующем месяце. А эти данные хотят в этом месяце получить. Можно конечно внешний скрипт написать и потихоньку для каждого id достать нужные данные. Но хотелось по красоте, средствами КХ решить задачу
ну можно выгружать отдельно по дням... SELECT id, uid, time WHERE time BETWEEN ... AND ...ORDER BY time DESC LIMIT BY id 10 к себе локально в csv а потом уже отдельно попробовать замутить что нибудь на clickhouse-local типа SELECT ... FROM file() на машине с большим кол-вом памяти но это все изврат... если оконки то https://fiddle.clickhouse.com/992ec93d-a514-451e-a92a-489e7efada84 но мне кажется тоже память жрать будет как не в себя...
попробуйте select ... from (select ..., row_number() over (partition by id order by time desc) as rnum) where rnum <= 10 может этот способ более ресурсоэффективен, но я лично не сравнивал
Мне кажеться надо копать в сторону SELECT id, max(toStartOfHour(time)) ts, uniq(uid) FROM table GROUP BY id ORDER BY ts desc limit 100 BY id... Это работает супер быстро и мы гарантированно получаем таймстемпы как минимум 100 последних uid для каждого id. Но как из них отфильтровать последние 100 пока не могу сообразить
на мой взгляд, скрипт в котором есть uniq / uniqExact — это не лучший вариант в задаче снижения потребления памяти ) но вам виднее, конечно
так попробуйте оконку, что я отправил зачем переизобретать row_number из коробки, который и используется, чтобы строки нумеровать
и либо я что-то не понимаю, но как этот код выдаст 100 последних uid, если он группирует по id и считает для него максимальное время и количество уникальных uid
оконные функции к сожалению в 20.12 всё таки не поддерживаются. (( Вот такой запрос очень шустро работает. и делает почти то, что надо... SELECT id,uid FROM table WHERE [id,toYYYYMMDD(time)] in (SELECT [id,max(toYYYYMMDD(time))] FROM table GROUP BY id) Но так как в течении дня может быть больше 100 записей (или наоборот, сильно меньше) то нужно вначале получить таймстемпы для последних 100 записей...
вот это у вас древняя система соберите тогда пары в массив select id, groupArray((id, timestamp)) group by id и отсортируйте его через лямбду в arraySort (если это, конечно, в версии 20 тоже работает) https://clickhouse.com/docs/en/sql-reference/functions/array-functions#array_functions-sort
Обсуждают сегодня