我创建了以下功能。当我们使用此函数编写SQL查询时,返回10K记录的查询将运行很长时间2小时。我发现性能问题是由于函数中CLOB的使用。当我将以下类型和函数中的CLOB引用更改为Varchar2时,查询将在一秒内运行。
但是,我不想将数据类型更改为Varchar2。我想把它当作CLOB。但是我怎样才能提高性能呢?
我明白我可以使用LISTAGG或其他oracle提供的字符串函数。但我希望数据类型为CLOB,并且想知道为什么执行会有这么大的差异。
以下是用户定义函数的代码。查询示例如下所示。
select my_concat(col1),my_concat(col2),my_concat(col3),my_concat(col4) from table group by col1,col2,col3,col4;
CREATE OR REPLACE TYPE "my_concat"
AUTHID CURRENT_USER
AS OBJECT (
curr_str clob,
STATIC FUNCTION odciaggregateinitialize (sctx IN OUT my_concat)
RETURN NUMBER,
MEMBER FUNCTION odciaggregateiterate (
SELF IN OUT my_concat,
p1 IN varchar2
)
RETURN NUMBER,
MEMBER FUNCTION odciaggregateterminate (
SELF IN my_concat,
returnvalue OUT clob,
flags IN NUMBER
)
RETURN NUMBER,
MEMBER FUNCTION odciaggregatemerge (
SELF IN OUT my_concat,
sctx2 IN my_concat
)
RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY "my_concat"
IS
STATIC FUNCTION odciaggregateinitialize (sctx IN OUT my_concat)
RETURN NUMBER
IS
BEGIN
sctx := my_concat (NULL);
RETURN odciconst.success;
END;
MEMBER FUNCTION odciaggregateiterate (
SELF IN OUT my_concat,
p1 IN varchar2
)
RETURN NUMBER
IS
BEGIN
IF (curr_str IS NOT NULL)
THEN
curr_str := curr_str || ',' || p1;
ELSE
curr_str := p1;
END IF;
RETURN odciconst.success;
END;
MEMBER FUNCTION odciaggregateterminate (
SELF IN my_concat,
returnvalue OUT clob,
flags IN NUMBER
)
RETURN NUMBER
IS
BEGIN
returnvalue := curr_str;
RETURN odciconst.success;
END;
MEMBER FUNCTION odciaggregatemerge (
SELF IN OUT my_concat,
sctx2 IN my_concat
)
RETURN NUMBER
IS
BEGIN
IF (sctx2.curr_str IS NOT NULL)
THEN
SELF.curr_str := SELF.curr_str || ',' || sctx2.curr_str;
END IF;
RETURN odciconst.success;
END;
END;
/
CREATE OR REPLACE FUNCTION my_func_cat (p1 varchar2)
RETURN clob
AGGREGATE USING my_concat;
/