안녕하세요
고수님들의 도움이 필요합니다
추출하려는 값들 아래와 같습니다. 그리고 이에 따른 쿼리는 바로 밑에 있습니다.
이런식으로 데이터 조회시 IN 절에 데이터 값이 많아지면 수행속도가 엄청 느려집니다. 몇십분에서 몇시간정도....
아래 쿼리를 효과적으로 튜닝 또는 어떤식으로 변경해야 할지 고수분들의 솔류션이 필요합니다.
데이터값 | 쿼리 결과값 | ||||||||||
A | B | C | D |
|
A | B | C | TO_KEY | |||
1 | A | A | A | 2 | 1 | A | A | A | 20200810_1 | ||
2 | B | B | B | 2 | 2 | A | A | A | 20200810_2 | ||
3 | C | C | C | 2 | 3 | B | B | B | 20200810_1 | ||
4 | D | D | D | 2 | 4 | B | B | B | 20200810_2 | ||
5 | E | E | E | 3 | 5 | C | C | C | 20200810_1 | ||
6 | F | F | F | 4 | 6 | C | C | C | 20200810_2 | ||
7 | G | G | G | 5 | 7 | D | D | D | 20200810_1 | ||
8 | H | H | H | 1 | 8 | D | D | D | 20200810_2 | ||
9 | I | I | I | 2 | 9 | E | E | E | 20200810_1 | ||
10 | E | E | E | 20200810_2 | |||||||
11 | E | E | E | 20200810_3 | |||||||
12 | F | F | F | 20200810_1 | |||||||
13 | F | F | F | 20200810_2 | |||||||
14 | F | F | F | 20200810_3 | |||||||
15 | F | F | F | 20200810_4 | |||||||
16 | G | G | G | 20200810_1 | |||||||
17 | G | G | G | 20200810_2 | |||||||
18 | G | G | G | 20200810_3 | |||||||
19 | G | G | G | 20200810_4 | |||||||
20 | G | G | G | 20200810_5 | |||||||
21 | H | H | H | 20200810_1 | |||||||
22 | I | I | I | 20200810_1 | |||||||
23 | I | I | I | 20200810_2 |
WITH DATA_T AS ( SELECT A , B , C , D AS ROW_CNT FROM TB_20200810_IMSI WHERE A IN ('A','B','C','D','E','F','G','H','I') ) SELECT A, B, C, TO_CHAR(SYSDATE, 'YYYYMMDD') || '_' || ROW_NUMBER() OVER(PARTITION BY A, B, C ORDER BY A, B, C) AS TO_KEY FROM DATA_T CONNECT BY LEVEL <= ROW_CNT GROUP BY A, B, C, LEVEL ORDER BY A, LEVEL
WITH TB_20200810_IMSI AS ( SELECT 'A' A , 'A' B ,'A' C ,2 D FROM DUAL UNION ALL SELECT 'B' , 'B' ,'B' ,2 D FROM DUAL UNION ALL SELECT 'C' , 'C' ,'C' ,2 D FROM DUAL UNION ALL SELECT 'D' , 'D' ,'D' ,2 D FROM DUAL UNION ALL SELECT 'E' , 'E' ,'E' ,3 D FROM DUAL UNION ALL SELECT 'F' , 'F' ,'F' ,4 D FROM DUAL UNION ALL SELECT 'G' , 'G' ,'G' ,5 D FROM DUAL UNION ALL SELECT 'H' , 'H' ,'H' ,1 D FROM DUAL UNION ALL SELECT 'I' , 'I' ,'J' ,2 D FROM DUAL ) SELECT A.A , A.B , A.C , TO_CHAR(SYSDATE, 'YYYYMMDD') || '_' || LV TO_KEY , A.D , B.LV FROM TB_20200810_IMSI A , ( SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= (SELECT MAX(D) FROM TB_20200810_IMSI ) ) B WHERE A.D >= B.LV ORDER BY A.A , B.LV
recursive 쿼리로 한번 해봤습니다. 컬럼 뒤에 1을 추가했습니다.
WITH TB_20200810_IMSI (A, B, C, D, E) AS ( SELECT * FROM ( SELECT 'A' A, 'A' B, 'A' C, 2 D, 1 E FROM DUAL UNION ALL SELECT 'B' , 'B' ,'B' ,2, 1 FROM DUAL UNION ALL SELECT 'C' , 'C' ,'C' ,2, 1 FROM DUAL UNION ALL SELECT 'D' , 'D' ,'D' ,2, 1 FROM DUAL UNION ALL SELECT 'E' , 'E' ,'E' ,3, 1 FROM DUAL UNION ALL SELECT 'F' , 'F' ,'F' ,4, 1 FROM DUAL UNION ALL SELECT 'G' , 'G' ,'G' ,5, 1 FROM DUAL UNION ALL SELECT 'H' , 'H' ,'H' ,1, 1 FROM DUAL UNION ALL SELECT 'I' , 'I' ,'I' ,2, 1 FROM DUAL ) t UNION ALL SELECT A, B, C, D, E + 1 FROM TB_20200810_IMSI WHERE E < D ) SELECT A, B, C, TO_CHAR(SYSDATE, 'YYYYMMDD') || '_' || E TO_KEY FROM TB_20200810_IMSI ORDER BY A, B, C, E
작성하신 쿼리가 카테시안곱이 발생하는 잘못 작성된 쿼리이고
우리집아찌님께서 답변주신 쿼리가 카테시안곱을 방지하는 정상 쿼리입니다.
Connect By LEVEL <= n 를 이용한 행복제 방식은 dual 과 같은 1건의 자료에만 적용하는 방법입니다.
여러건의 집합(테이블)에 직접 적용하면 안됩니다.
http://gurubee.net/article/55635