PLSQL中的CLOB性能问题

时间:2017-03-31 14:01:26

标签: oracle oracle11g clob

我创建了以下功能。当我们使用此函数编写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;
/

0 个答案:

没有答案