본문 바로가기

정리/Database

SQL 구분자 기준으로 여러행으로 나누기

728x90

WITH temp AS
        (
                SELECT
                        A.COL_0                        ,
                        A.COL1                         ,
                        A.COL2                         ,
                        LEVEL             AS lvl       ,
                        SUBSTR( A.COL1, INSTR(A.COL1, '$', 1, LEVEL) + 1, INSTR(A.COL1 || '$', '$', 1, LEVEL + 1) - INSTR(A.COL1, '$', 1, LEVEL) - 1 ) AS col1_split,
                        SUBSTR( A.COL2, INSTR(A.COL2, '$', 1, LEVEL) + 1, INSTR(A.COL2 || '$', '$', 1, LEVEL + 1) - INSTR(A.COL2, '$', 1, LEVEL) - 1 ) AS col2_split
                FROM
                        AAA A CONNECT BY LEVEL <= LENGTH(A.COL1) - LENGTH(REPLACE(A.COL1, '$', '')) + 1
                        AND PRIOR A.COL1       = A.COL1
                        AND PRIOR SYS_GUID() IS NOT NULL ),
        temp2_formatted AS
        (
                SELECT
                        COL_0             ,
                        COL1 AS col1_split,
                        COL2 AS col2_split
                FROM
                        temp2 )
-- 두 테이블의 데이터를 합쳐서 결과 조회
SELECT
        COL_0     ,
        col1_split,
        col2_split
FROM
        temp
WHERE
        col1_split IS NOT NULL
OR      col2_split IS NOT NULL

UNION ALL

SELECT
        COL_0     ,
        col1_split,
        col2_split
FROM
        temp2_formatted;

 

쿼리에서 $ 구분자가 많은 경우 정규 표현식(REGEXP_SUBSTR 및 REGEXP_COUNT) 함수가 여러 번 호출되면서 성능 문제나 무한 루프가 발생할 수 있습니다. 특히, $가 반복적으로 많이 들어가 있는 경우에는 이런 문제가 더 심각해질 수 있습니다.

이 문제를 해결하기 위해 정규 표현식 대신 단순 문자열 함수를 활용하여 $ 구분자를 처리하는 방식으로 쿼리를 수정해볼 수 있습니다.

단순 문자열 함수(INSTR와 SUBSTR)를 사용한 개선된 쿼리

정규 표현식을 사용하지 않고 INSTR와 SUBSTR을 사용하여 $ 구분자를 기준으로 값을 추출하는 방식입니다.

  1. INSTR와 SUBSTR 사용:
    • INSTR로 $의 위치를 찾고 SUBSTR을 이용해 구분자로 분리된 데이터를 추출합니다.
    • COL1 || '$'를 사용하여 마지막 값의 길이를 계산할 때 $를 붙여 경계를 쉽게 잡도록 처리합니다.
  2. 반복 조건 계산:
    • LENGTH(A.COL1) - LENGTH(REPLACE(A.COL1, '$', '')) + 1은 $의 개수를 세는 방식으로, 필요한 반복 횟수를 계산합니다. 이 방식은 정규 표현식을 사용하지 않으므로 성능이 더 좋을 수 있습니다.

이렇게 변경하면 정규 표현식을 사용하지 않기 때문에 실행 속도가 개선될 수 있으며, $ 구분자가 많아도 메모리 부족 문제가 줄어들 가능성이 높습니다.