Я написал алгоритм самой длинной общей подпоследовательности в функции PL / SQL. Мне нужна только длина подпоследовательности в качестве вывода.
Теперь моя самая большая проблема - это скорость функции при использовании этой функции для сотен тысяч записей. Существует вложенный цикл, который заполняет объект многомерного типа таблицы.
У меня есть две таблицы, одна из которых содержит 1 миллион записей (строка), а другая - почти 28 000 записей (строка).
Требуется сопоставить каждую запись в таблице 1 с каждой записью таблицы 2 и получить длину LCS для каждой.
Согласно моему анализу, вложенный цикл занимает максимальное количество времени.
/*
LCS LOGIC
*/
1 CREATE OR REPLACE
2 FUNCTION GET_LCS_LENGTH(
3 table1_string IN NVARCHAR2,
4 table2_string IN NVARCHAR2)
5 RETURN NUMBER
6 AS
7 TYPE t_number_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
8 TYPE t_bidimensional_number_array IS TABLE OF t_number_array INDEX BY BINARY_INTEGER;
9 matrix t_bidimensional_number_array ;
10 --...
11 BEGIN
12 len_str1 := LENGTH(table1_string);
13 len_str2 := LENGTH(table2_string);
14 matrix(1)(1) := 0;
15 FOR i IN 2..(len_str2+1)
16 LOOP
17 matrix(i)(1) := 0;
18 ch1 := SUBSTR(table2_string,i-1,1);
19 FOR j IN 2..(len_str1+1)
20 LOOP
21 matrix(1)(j) := 0;
22 ch2 := SUBSTR(table1_string,j-1,1);
23 IF ch1 = ch2 THEN
24 matrix(i)(j) := matrix(i - 1)(j - 1) + 1;
25 ELSE
26 matrix(i)(j) := greatest(matrix(i)(j - 1),matrix(i - 1)(j));
27 END IF;
28 END LOOP;
29 END LOOP;
30 lcs_Dist := matrix(len_str2+1)(len_str1+1);
31 matrix.DELETE;
32 END;
/*
LCS LOGIC END
*/
Как я могу заменить этот вложенный цикл for, чтобы получить длину LCS или использовать другую логику, или как оптимизировать этот код дальше?
В настоящее время, когда одна запись в таблице 1 сопоставляется с каждыми 28 000 записей в таблице 2, это занимает 5 секунд, что обходится мне дорого.
Он должен работать за доли секунды для 28 000 записей, тогда только я смогу достичь определенной цели с другими 1 миллионами записей.