提供以下Oracle功能:
CREATE or REPLACE FUNCTION foo(id NUMBER, category VARCHAR) RETURN CHAR IS
TYPE MY_ARRAY2 IS TABLE OF NUMBER;
MY_ARRAY MY_ARRAY2;
BEGIN
SELECT my_id BULK COLLECT INTO my_array FROM my_table
RETURN (
CASE WHEN category = 'FOO' AND (id member of MY_ARRAY)
THEN 'Y'
ELSE 'N'
END
);
END;
查找的本质是什么
SELECT my_id BULK COLLECT INTO my_array FROM my_table
或者换句话说,有什么我可以添加到此行或其他地方以加快查找速度的东西-也许是索引吗?
答案 0 :(得分:3)
您所能做的就是对MAX
或COUNT
使用单个选择
AS
..
..
v_retval VARCHAR2(10);
SELECT MAX(CASE
WHEN category = 'FOO'
AND id = my_id
THEN 'Y'
ELSE 'N'
END) INTO v_retval
FROM my_table;
RETURN v_retval;
这取决于字符串“ Y”>“ N”的事实。您也可以使用COUNT(CASE ..
和其他情况下的where count > 1 THEN 'Y'
在id(或表中引用的其他列)上添加索引将有助于加快查询速度
请注意,最好使用p_id
和p_category
形式的过程参数以避免冲突
答案 1 :(得分:2)
BULK COLLECT
只是一种使用多行结果集填充PL / SQL集合(数组)的方法。如果没有它,我们将只能使用单行填充标量值。
就性能而言,最大的影响实际上是查询的效率,您可以按照通常的方式进行调整。否则,BULK COLLECT
的性能在很大程度上是透明的=除非您选择大量的行。这很重要,因为集合驻留在会话级内存中,因此,如果您的PGA配置不正确,那么非常大的集合(许多行,许多列)可能导致分页(写入磁盘)。
如果遇到内存问题,可以将BULK COLLECT
与LIMIT
子句一起使用,以获取记录的一小部分,并使用流水线函数实现将其吐出。但是您确实应该首先查看填充查询的性能。
那么从数组中查找一个值是O(n)?
在一个集合中循环是线性的(最好)。使用SQL限制结果集通常比选择所有内容并在循环中过滤结果集更有效。 SQL在处理集合方面非常高效。换句话说,Kaushik's solution。
答案 2 :(得分:0)
这将更具可读性。确保可以将索引放在表的id
字段中。
如果id
不是主键(即可能有重复项),请在ROWNUM = 1
子句中使用WHERE
。
FUNCTION foo(p_id NUMBER, p_category VARCHAR) RETURN CHAR IS
n NUMBER;
BEGIN
SELECT id INTO n FROM table WHERE id = p_id AND p_category = 'FOO';
RETURN 'Y';
EXCEPTION WHEN OTHERS THEN
RETURN 'N';
END;