我需要优化当前的PL / SQL函数:
CREATE OR REPLACE FUNCTION tkt_get_underlying(n_input number)
RETURN t_table_of_number
IS
ret t_table_of_number;
CURSOR c IS SELECT n_number FROM t_table WHERE n_prop_1=n_input OR n_prop_2=n_input OR n_prop_3=n_input;
BEGIN
ret := t_table_of_number();
OPEN c;
FETCH c BULK COLLECT INTO ret;
CLOSE c;
RETURN ret;
END;
我希望能够将数组作为参数,但是,我不知道如何构建我的光标以获取数组。我想我可以使用IN
声明,但你可以帮我解决这个问题吗?
编辑:
根据Justin Cave提供的解决方案,它将成为:
CREATE OR REPLACE FUNCTION tkt_get_underlying(n_inputs t_table_of_number)
RETURN t_table_of_number
IS
ret t_table_of_number;
CURSOR c IS SELECT n_number FROM t_table WHERE n_prop_1 IN (SELECT column_value FROM TABLE(n_inputs))
OR n_prop_2 IN (SELECT column_value FROM TABLE(n_inputs))
OR n_prop_3 IN (SELECT column_value FROM TABLE(n_inputs));
BEGIN
ret := t_table_of_number();
OPEN c;
FETCH c BULK COLLECT INTO ret;
CLOSE c;
RETURN ret;
END;
然而,多个SELECT column_value FROM TABLE(n_inputs)
减慢了整个功能。我该如何改进?
答案 0 :(得分:2)
如果要传递n_input
个值的集合并返回相同的t_table_of_number
集合(即,您不需要知道输出数组的哪个元素与哪个元素相关联输入数组)
CREATE OR REPLACE FUNCTION tkt_get_underlying(p_inputs t_table_of_number)
RETURN t_table_of_number
IS
ret t_table_of_number;
CURSOR c
IS SELECT n_number
FROM t_table
WHERE n_prop IN (SELECT column_value
FROM TABLE( p_inputs ) );
BEGIN
OPEN c;
FETCH c BULK COLLECT INTO ret;
CLOSE c;
RETURN ret;
END;
这假设可能插入ret
集合的元素数量仍然合理地同时保存在PGA内存中。根据具体情况,您可能希望将其转换为流水线表函数,以限制所需的PGA内存量。
答案 1 :(得分:1)
Oracle使用嵌套表获取基数错误,因为它不知道实际存在多少行。尝试使您的功能看起来像:
CREATE OR REPLACE FUNCTION tkt_get_underlying(n_inputs t_table_of_number)
RETURN t_table_of_number
IS
ret t_table_of_number;
CURSOR c IS SELECT n_number FROM t_table WHERE n_prop_1 IN (SELECT /*+ cardinality(ni 1) */ column_value FROM TABLE(n_inputs) ni)
OR n_prop_2 IN (SELECT /*+ cardinality(ni 1) */ column_value FROM TABLE(n_inputs) ni)
OR n_prop_3 IN (SELECT /*+ cardinality(ni 1) */ column_value FROM TABLE(n_inputs) ni);
BEGIN
ret := t_table_of_number();
OPEN c;
FETCH c BULK COLLECT INTO ret;
CLOSE c;
RETURN ret;
END;
注意,如果您知道嵌套表中预期的行数,请使您的基数提示准确无误。此外,如果在嵌套表中放置太多行,Oracle可能会以次优的方式执行,因为您认为嵌套表中的行数少于它实际拥有的行数。
答案 2 :(得分:0)
感谢您的帮助,我终于找到了符合我需求的优化。现在查询如下:
CREATE OR REPLACE FUNCTION tkt_get_underlying(n_inputs t_table_of_number)
RETURN t_table_of_number
IS
ret t_table_of_number;
CURSOR c IS SELECT t.n_number FROM t_table t, (SELECT column_value /*+cardinality(t_inputs 100) */ c FROM TABLE(n_inputs)) t_inputs
WHERE t_inputs.c = t.n_prop_1
OR t_inputs.c = t.n_prop_2
OR t_inputs.c = t.n_prop_3;
BEGIN
ret := t_table_of_number();
OPEN c;
FETCH c BULK COLLECT INTO ret;
CLOSE c;
RETURN ret;
END;
它的JOIN优于IN