Oracle:通过定界符在多列上拆分数据并显示每一行

时间:2018-09-21 06:57:27

标签: regex oracle performance oracle11g

我想基于定界符将每一列数据拆分为一行,并显示为多行。我需要最快的方法来实现这一目标。我的架构和当前查询用于拆分记录,如下所示:

fmt -w 454 file

使用表格拆分查询

CREATE TABLE APP_SPECS
  (
    SPEC_ID          NUMBER PRIMARY KEY,
    SPEC_NAME        VARCHAR2(4000),
    SPEC_DESCRIPTION VARCHAR2(4000),
    SPEC_TYPE        VARCHAR2(4000)
  );
/
INSERT INTO APP_SPECS VALUES (1, 'SPEC 1' || CHR(10) || 'SPEC 2', 'SPEC DESC' || CHR(10) || 'SPEC DESC', 'TYPE 1' || CHR(10) || 'TYPE 2');
/
INSERT INTO APP_SPECS VALUES (2, 'SPEC 3' || CHR(10) || 'SPEC 4', 'SPEC DESC 3' || CHR(10) || 'SPEC DESC 4', 'TYPE 3' || CHR(10) || 'TYPE 4');
/
INSERT INTO APP_SPECS VALUES (3, 'SPEC 5' || CHR(10) || 'SPEC 6', CHR(10) || 'SPEC DESC 6', 'TYPE 5' || CHR(10) || 'TYPE 6');
/
INSERT INTO APP_SPECS VALUES (4, 'SPEC 7' || CHR(10) || 'SPEC 8' || CHR(10) || 'SPEC 9', 'SPEC DESC 7', 'TYPE 7' || CHR(10) || 'TYPE 8');
/
COMMIT;
/

使用上述查询,我​​们将获得以下输出。

WITH APP_SPECS_CTE AS
  (SELECT REGEXP_SUBSTR(REPLACE(SPEC.SPEC_NAME,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_NAME ,
    REGEXP_SUBSTR(REPLACE(SPEC.SPEC_DESCRIPTION,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_DESCRIPTION ,
    REGEXP_SUBSTR(REPLACE(SPEC.SPEC_TYPE,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_TYPE,
    SPEC_ID
  FROM APP_SPECS SPEC
    CONNECT BY LEVEL          <= LENGTH(REPLACE(SPEC.SPEC_NAME,CHR(10),',')) - LENGTH(REPLACE(REPLACE(SPEC.SPEC_NAME,CHR(10),','), ',')) + 1
  AND PRIOR SPEC_ID            = SPEC_ID
  AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
  )
SELECT SPEC_ID, SPEC_NAME, SPEC_DESCRIPTION, SPEC_TYPE FROM APP_SPECS_CTE;

我的APP_SPEC表中有300万条记录。当我执行它需要5分钟以上。有人可以检查我的查询并更正我吗,

Oracle实例详细信息:Octa核心处理器,64 GB RAM。

1 个答案:

答案 0 :(得分:0)

  

我希望查询执行少于10秒。

在不到十秒钟的时间内查询300万条记录本身就非常具有挑战性。甚至在我们考虑CPU密集型正则表达式处理之前。在用户界面中显示该行数?不可能。但实际上,它是3m的倍数,因为您要将每条记录分成几行。真的不可能。

但是这里真正的要求是什么?您的用户是否真的想每次看到三百万行?还是他们真的只是要查询一小部分行,例如一个SPEC_ID?因为这应该在十秒钟之内。

但是,如果您必须查询整个表,则无法用比现在少得多的时间来执行此操作。您将不得不将数据模型重新设计为“第一范式”。这可能不需要您想象的那么多的工作:只要重构UI,您就可以使用视图来维护更好的数据模型上的当前投影。