Мне нужно написать запрос сортировки записей по динамически рассчитанным критериям.В каждой ячейке имеется двумерный массив 12x12, в котором указано количество точек.Точки распределяются вдоль диагоналей (т.е. все элементы главной диагонали дают 6 баллов)
+----+---+---+---+---+---+---+---+---+---+----+----+----+
| № | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
+----+---+---+---+---+---+---+---+---+---+----+----+----+
| 1 | 6 | 4 | 5 | 2 | 7 | 3 | 1 | 6 | 7 | 2 | 5 | 6 |
| 2 | 4 | 6 | 4 | 5 | 2 | 7 | 3 | 1 | 6 | 7 | 2 | 5 |
| 3 | 5 | 4 | 6 | 4 | 5 | 2 | 7 | 3 | 1 | 6 | 7 | 2 |
| 4 | 2 | 5 | 4 | 6 | 4 | 5 | 2 | 7 | 3 | 1 | 6 | 7 |
| 5 | 7 | 2 | 5 | 4 | 6 | 4 | 5 | 2 | 7 | 3 | 1 | 6 |
| 6 | 3 | 7 | 2 | 5 | 4 | 6 | 4 | 5 | 2 | 7 | 3 | 1 |
| 7 | 1 | 3 | 7 | 2 | 5 | 4 | 6 | 4 | 5 | 2 | 7 | 3 |
| 8 | 6 | 1 | 3 | 7 | 2 | 5 | 4 | 6 | 4 | 5 | 2 | 7 |
| 9 | 7 | 6 | 1 | 3 | 7 | 2 | 5 | 4 | 6 | 4 | 5 | 2 |
| 10 | 2 | 7 | 6 | 1 | 3 | 7 | 2 | 5 | 4 | 6 | 4 | 5 |
| 11 | 5 | 2 | 7 | 6 | 1 | 3 | 7 | 2 | 5 | 4 | 6 | 4 |
| 12 | 6 | 5 | 2 | 7 | 6 | 1 | 3 | 7 | 2 | 5 | 4 | 6 |
+----+---+---+---+---+---+---+---+---+---+----+----+----+
Есть таблица с результатами, вот ее структура:
create table result_schema (
user_id bigint not null,
result_1 integer not null,
result_2 integer not null,
result_3 integer not null,
result_4 integer not null,
result_5 integer not null
);
Столбцы «result_ *» содержат номер столбца из массива.Мне нужно написать функцию для расчета очков.Аргументы функции: значение из столбца result_ * и некоторое ссылочное значение (порядковый номер строки в массиве)
Точки должны быть рассчитаны для каждого поля result_ * и суммированы, а результат отсортирован по убываниюпорядок.
На данный момент я написал функцию:
CREATE OR REPLACE FUNCTION rank(row integer, column integer) RETURNS integer AS $$
DECLARE
diagonal_number integer;
BEGIN
diagonal_number = row - column + 1;
if (diagonal_number < 1) then
diagonal_number = abs(diagonal_number) + 2;
end if;
case diagonal_number
when 1, 12 then return 6;
when 2 then return 4;
when 3, 11 then return 5;
when 4, 10 then return 2;
when 5, 9 then return 7;
when 6, 8 then return 3;
when 7 then return 1;
else
return 0; -- ERROR!
end case;
END; $$
LANGUAGE PLPGSQL;
А вот запрос для извлечения данных:
select user_id, (
rank(6, result_1) +
rank(1, result_2) +
rank(4, result_3) +
rank(8, result_4) +
rank(9, result_5)
) as rate
from result_schema
where user_id between 1 and 1000
order by rate desc;
Есть 5 000 000 элементов втаблица с результатами, но выборка проходит только 1000 каждый.И это занимает ~ 700 мс.Есть ли способ оптимизировать выбор или ускорить поиск другими способами?Можно ли использовать другую СУБД вместо postgres?