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을 사용하여 $ 구분자를 기준으로 값을 추출하는 방식입니다.
- INSTR와 SUBSTR 사용:
- INSTR로 $의 위치를 찾고 SUBSTR을 이용해 구분자로 분리된 데이터를 추출합니다.
- COL1 || '$'를 사용하여 마지막 값의 길이를 계산할 때 $를 붙여 경계를 쉽게 잡도록 처리합니다.
- 반복 조건 계산:
- LENGTH(A.COL1) - LENGTH(REPLACE(A.COL1, '$', '')) + 1은 $의 개수를 세는 방식으로, 필요한 반복 횟수를 계산합니다. 이 방식은 정규 표현식을 사용하지 않으므로 성능이 더 좋을 수 있습니다.
이렇게 변경하면 정규 표현식을 사용하지 않기 때문에 실행 속도가 개선될 수 있으며, $ 구분자가 많아도 메모리 부족 문제가 줄어들 가능성이 높습니다.
'정리 > Database' 카테고리의 다른 글
서브쿼리를 활용하여 조건을 주고 갱신하는 법 (1) | 2024.10.26 |
---|---|
[Database] 기본 문법 Select , Delete ,Insert , Update (0) | 2023.11.14 |
[R] R과 Database 연동 (R과 DB 연동) (0) | 2018.12.02 |
Ubuntu서버에서 MariaDB 원격 접속하기 (0) | 2018.10.18 |