我正在研究一种从一组数字中获得完美匹配的函数(最小值为1,最大值为25)。
我在下面的DDL中提供了创建表的信息,还有我正在使用的insert语句和代码,这些代码目前存在性能问题。
运行以下代码。
如果记录数为20,将在2分钟内运行。
我在这里给出的总记录为33,因此将花费大量时间,不确定是否完成。
任何输入都会有很大的帮助。
CREATE TABLE xx_perfect_combi_test
(
trx_id NUMBER
,trx_val NUMBER
);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051303, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051304, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051305, 25);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051306, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051307, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051308, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051309, 24);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051310, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051311, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051312, 23);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051313, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051314, 22);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051315, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051316, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051317, 21);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051318, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051319, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051320, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051321, 20);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051322, 18);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051323, 17);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051324, 11);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051325, 9);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051326, 8);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051327, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051328, 6);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051329, 4);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051330, 3);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051331, 1);
INSERT INTO xx_perfect_combi_test (trx_id, trx_val) VALUES (2051332, 1);
COMMIT;
我的程序:
DECLARE
ln_total_sum NUMBER := 315;
ln_orig_diff NUMBER := ln_total_sum;
ln_curr_diff NUMBER;
lv_trx_ids VARCHAR2 (4000);
lv_trx_ids_buff VARCHAR2 (4000);
lv_dummy_return VARCHAR2 (4000);
FUNCTION perfect_combo (p_curr_sum IN NUMBER
,p_curr_vals IN VARCHAR2
,p_rownumber IN NUMBER)
RETURN VARCHAR2
IS
lv_buf_trx_id VARCHAR2 (4000);
BEGIN
FOR c1 IN (SELECT *
FROM (SELECT stg2.*
,ROW_NUMBER () OVER (ORDER BY stg2.trx_val DESC) AS rownumber1
FROM xx_perfect_combi_test stg2)
WHERE rownumber1 > p_rownumber
ORDER BY trx_val DESC) LOOP
--dbms_output.put_line ('p_curr_sum: ' || p_curr_sum);
--dbms_output.put_line ('p_curr_vals: ' || p_curr_vals);
--dbms_output.put_line ('p_rownumber: ' || p_rownumber);
--dbms_output.put_line ('---------------------------------------------------');
IF ( (p_curr_sum + c1.trx_val) = ln_total_sum)
THEN
lv_buf_trx_id := p_curr_vals;
lv_buf_trx_id := lv_buf_trx_id || c1.trx_id || ';';
lv_trx_ids := lv_buf_trx_id;
RETURN lv_trx_ids;
ELSIF (p_curr_sum + c1.trx_val) > ln_total_sum
THEN
ln_curr_diff := ln_total_sum - p_curr_sum;
IF ln_curr_diff < ln_orig_diff
THEN
ln_orig_diff := ln_curr_diff;
lv_trx_ids_buff := p_curr_vals;
END IF;
CONTINUE;
ELSIF (p_curr_sum + c1.trx_val) < ln_total_sum
THEN
ln_curr_diff := ln_total_sum - (p_curr_sum + c1.trx_val);
lv_buf_trx_id := p_curr_vals;
lv_buf_trx_id := lv_buf_trx_id || c1.trx_id || ';';
IF ln_curr_diff < ln_orig_diff
THEN
ln_orig_diff := ln_curr_diff;
lv_trx_ids_buff := lv_buf_trx_id;
END IF;
lv_dummy_return := perfect_combo ( (p_curr_sum + c1.trx_val), lv_buf_trx_id, c1.rownumber1);
END IF;
END LOOP;
RETURN NULL;
END perfect_combo;
BEGIN
lv_dummy_return := perfect_combo (0, NULL, 0);
DBMS_OUTPUT.put_line ('lv_trx_ids: ' || lv_trx_ids);
DBMS_OUTPUT.put_line ('lv_trx_ids_buff: ' || lv_trx_ids_buff);
END;
找到匹配项后,我们必须完全退出函数调用。我创建了一个全局变量,并检查是否找到匹配项,然后从函数调用中完全返回。这样,程序就可以快速完成。