184 похожих чатов

Дано: CREATE TABLE default.src_cases_11_1 ( case_id Int64,

hash_arr Array(UInt64)
)
ENGINE = MergeTree
ORDER BY case_id
SETTINGS index_granularity = 8192

В ней 27 200 строк, массивы в hash_arr содержат от 1 до 14 элементов.

Мне нужно сравнить значения hash_arr в каждой строке с каждой (перебором по возрастанию case_id) и для каждой строки найти case_id первой, соответствующую выражению "кол-во общих элементов в массивах, деленное на половину суммы длин сравниваемых массивов больше 0.25"

Написал такой запрос. реализующий 2 вложенных цикла по массиву массивов :

select arrayMap(x -> case_id_arr_arr[arrayFirstIndex(a -> a > 0.25, arrayMap(y -> length(arrayIntersect(x, y)) / (length(x) + length(y)), a.hash_arr_arr))], a.hash_arr_arr)
from (
select groupArray(hash_arr) hash_arr_arr, groupArray(case_id) case_id_arr_arr
from src_cases_11_1
) a

Получаю: "Code: 241, e.displayText() = DB::Exception: Memory limit (for query) exceeded: would use 24.01 GiB (attempt to allocate chunk of 4295098368 bytes), maximum: 23.28 GiB: while executing 'FUNCTION arrayMap(__lambda :: 2, hash_arr_arr :: 3) -> arrayMap(lambda(tuple(x), arrayElement(case_id_arr_arr, arrayFirstIndex(lambda(tuple(a), greater(a, 0.25)), arrayMap(lambda(tuple(y), divide(length(arrayIntersect(x, y)), plus(length(x), length(y)))), hash_arr_arr)))), hash_arr_arr) Array(Int64) : 1' (version 21.3.8.76 (official build))"

Что делать ? По моим прикидкам, объем массива hash_arr_arr в памяти никак не более 2 Мб, объем итогового массива 27200 * 8 - тоже явно не хватит для переполнения.

При ограничении в исходной таблице в 9-10 тысяч строк запрос успешно отрабатывает за примерно 30 секунд - на мой взгляд, тоже многовато

6 ответов

14 просмотров
Anatoly Seryakov- Автор вопроса

Такое ощущение, что после выхода из arrayFirstIndex в очередной итерации - ее данные остаются в памяти. Тогда да, 27 тысяч раз по 2 Мб вполне могут вызвать переполнение при 24 Гб свободных

https://kb.altinity.com/altinity-kb-functions/array-like-memory-usage/ Это ожидаемо, и это не бага

КХ делает копию массивов переданных в лямбду для каждой итерации как тупое решение попробуйте max_threads = 1 но скорее всего это нельзя решить через arrayMap и массивы, надо пробовать разворачивать массивы в строки и делать джойн

Anatoly Seryakov- Автор вопроса
Denny [Altinity]
КХ делает копию массивов переданных в лямбду для к...

Именно с этого и начал (данные в src_cases_11_1 это результат groupArray исходной таблицы с 500к) - та же беда, нехватка памяти

Anatoly Seryakov- Автор вопроса
Denny [Altinity]
КХ делает копию массивов переданных в лямбду для к...

Вот, я не стал сворачивать левую часть сравнения в массив, только правую и по ней итерирую с помощью arrayMap: with src as ( select groupArray(hash_arr) hash_arr_arr, groupArray(case_id) case_id_arr_arr from src_cases_11_1 ) select src.case_id_arr_arr[arrayFirstIndex(a -> a > 0.25, arrayMap(y -> length(arrayIntersect(s.hash_arr, y)) / (length(s.hash_arr) + length(y)), src.hash_arr_arr))] from src_cases_11_1 s cross join src DB::Exception: Memory limit (for query) exceeded: would use 24.02 GiB (attempt to allocate chunk of 8589934592 bytes), maximum: 23.28 GiB (version 21.3.8.76 (official build))

Anatoly Seryakov- Автор вопроса
Denny [Altinity]
КХ делает копию массивов переданных в лямбду для к...

А после завершения каждой итерации эти копии удаляются ? Если нет, то возникают серьезные вопросы к реализации arrayMap в CH

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Карта сайта