Есть массивы по 4k значений. Надо посчитать разность между элементами двух масивов, возвести её в квадрат, сложить и извлечь корень. Это будет «расстояние». Задача: найти десяток массивов с минимальным расстоянием.
На тестовом примере в 6k массивов, эластик отрабатывает за 8 секунд, постгрес за двадцать.
CREATE OR REPLACE FUNCTION my_dist(l double precision[], r double precision[]) RETURNS double precision AS $$
DECLARE
s double precision;
al int;
BEGIN
s := 0;
FOR i IN 1..al LOOP
s := s + ((l[i] - r[i]) * (l[i] - r[i]));
END LOOP;
RETURN sqrt(s);
END;
$$ LANGUAGE plpgsql;
Ну ок, пока я изучал, что можно исправить, выяснил, что введение доп. переменной j := j + 1
снижает производительность раза в полтора, странно, да? Отож. Тогда, я покумекал и сделал так:
CREATE OR REPLACE FUNCTION my_dist2(l double precision[], r double precision[]) RETURNS double precision AS $$
select sqrt(sum((li-ri)^2)) from unnest(l, r) as names(li, ri);
$$ LANGUAGE sql;
Эта штукенция уже отрабатывает за 11 секунд (если не в виде процедуры, а сразу встраивать в запрос, то 14-16секунд), в принципе, близко к эластику, но хотелось бы ещё быстрее. Ибо эластик для этой задачи подходит крайне хреново.