조회쿼리 입니다.
WITH 테이블 자체 조회시에는 속도에 문제가 없으나,
임시테이블을 이용하여 아래처럼 조회를 하면 속도저하가 너무 심합니다.
WITH TB( ..중략..)
SELECT RANK,
,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS doorA
,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS doorB
,SUM( CASE WHEN A.BTYPE = '2' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS moldA
,SUM( CASE WHEN A.BTYPE = '2' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS moldB
,SUM( CASE WHEN A.BTYPE = '3' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS pvcA
,SUM( CASE WHEN A.BTYPE = '3' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS pvcB
,SUM( CASE WHEN A.BTYPE = '4' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS floorA
,SUM( CASE WHEN A.BTYPE = '4' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS floorB
,SUM( CASE WHEN A.BTYPE = '5' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS bigA
,SUM( CASE WHEN A.BTYPE = '5' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS bigB
,SUM( CASE WHEN A.BTYPE = '6' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS wallA
,SUM( CASE WHEN A.BTYPE = '6' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS wallB
,SUM( CASE WHEN A.BTYPE = '7' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS artA
,SUM( CASE WHEN A.BTYPE = '7' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS artB
,SUM(A.AMT) AS total
FROM TB A
WHERE 1 = 1
GROUP BY RANK;
,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS doorA 로 검색해오는 컬럼 속도를 향상시킬 쿼리가 있을까요..?
With 바깥쪽은 문제 없어 보입니다. With 안쪽 쿼리도 보여주세요.
WITH 절입니다~!
WITH TB AS (
SELECT
B.RANK,PB.CUST
,FS02_GET_CUST_NM(PB.CUST, TO_CHAR(SYSDATE,'YYYYMMDD')) AS CUST_NM
,PC.MNG_DEPT
,FC00_GET_DEPT_NM(PC.MNG_DEPT, PB.YYMM||'01') AS MNG_DEPT_NM
,PC.MNG_EMP
,FC00_GET_EMP_NM(PC.MNG_EMP, PB.YYMM||'01') AS MNG_EMP_NM
,FC00_GET_EMP_RANK(PC.MNG_EMP, PB.YYMM||'01') AS EMP_DEPT
,PB.YYMM
,PB.LTYPE
,PB.MTYPE
,PB.STYPE
,PB.ENTRY_YN
,PB.TYPE
,PB.AMT
FROM(
SELECT DENSE_RANK() OVER ( ORDER BY PP.CUST ) AS RANK
,PP.CUST
,PP.YYMM
,SS.CODE
,SS.LTYPE
,SS.MTYPE
,SS.STYPE
,CASE WHEN NVL(PE.ENTRY_TYPE,'A') IN ('C','D') THEN 'Y' ELSE 'N' END ENTRY_YN
,PP.TYPE
,SUM(PP.AMT) AS AMT
FROM TS01_PROJ_SUMMARY PP
JOIN (
SELECT DISTINCT CODE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
--SELECT CODE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
FROM TC00_CODE_LIST
WHERE 1 = 1
AND CODE_GROUP = 'SALES_TYPE'
AND TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN FROM_DATE AND TO_DATE
AND DEL_DATE IS NULL
)SS
ON PP.SALES_TYPE = SS.CODE
JOIN TS01_PROJ_CONST_ENTRY PE
ON PP.CUST = PE.CUST
AND PP.SALES_TYPE = PE.SALES_TYPE
WHERE 1=1
AND PP.TYPE <> 'A'
GROUP BY PP.CUST, PP.YYMM, SS.CODE, SS.LTYPE, SS.MTYPE, SS.STYPE, NVL(PE.ENTRY_TYPE,'A'), PP.TYPE
UNION ALL
SELECT DENSE_RANK() OVER ( ORDER BY PP.CUST ) AS RANK
,PP.CUST
,PP.YYMM
,SS.PTYPE
,SS.LTYPE
,SS.ATYPE
,SS.BTYPE
,'N' AS ENTRY_YN
,PP.TYPE
,SUM(PP.AMT) AS AMT
FROM TB_SUMMARY PP
JOIN (
SELECT DISTINCT REMARK6 AS PTYPE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
FROM TC00_CODE_LIST
WHERE 1 = 1
AND CODE_GROUP = 'SALES_TYPE'
AND TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN FROM_DATE AND TO_DATE
AND DEL_DATE IS NULL
)SS
ON PP.SALES_TYPE = SS.PTYPE
WHERE 1=1
AND PP.TYPE = 'A'
GROUP BY PP.CUST, PP.YYMM, SS.PTYPE, SS.LTYPE, SS.MTYPE, SS.STYPE, TYPE
)PB
JOIN TS01_PROJ_CONST_RANK PC
ON PB.CUST = PC.S_CUST
JOIN(
SELECT RANK, CUST
FROM TS01_PROJ_CONST_RANK
WHERE YY = TO_CHAR(TO_DATE(:pToDate, 'YYYYMM'), 'YYYY')
GROUP BY RANK, CUST
ORDER BY RANK
) B
ON PB.CUST = B.CUST
AND PC.YY = TO_CHAR(TO_DATE(:toDate, 'YYYYMM'), 'YYYY')
WHERE 1 = 1
AND YYMM BETWEEN :fromDate AND :toDate
)
WITH 구문 안에 불필요한 구문들이 너무 많네요.
- 사용자함수, Distinct, Group By, dense_rank, Order By, 등등
- 컬럼명이나 알리아스가 예약어인 rank 라는 것도 마음에 들지 않구요.
이 쿼리가 맞는 쿼리인지도 의문입니다.
- atype, btype 이 혼용되고 있는데? mtype, stype 이 아닌가 싶고.
- :pToDate 와 :toDate 가 사용되는데? 다른 값인지? 같은 값인지?
- Distinct 는 왜 하는건지?
의문 가는 부분은 너무 많은데
테이블 정보와 관계 등을 알 수가 없어 섣부르게 접근하기가 망설여지네요.
지금 이 상태로는 쿼리를 제가 고쳐드릴 수가 없습니다.
일단은 불필요한 요소들부터 제거해 보세요.
- 사용자함수, Distinct, Group By, dense_rank, Order By, 등등
네 감사합니다~! 말씀하신대로 불필요한 부분을 제거하고 재실행해봐야겠습니다. 정말 감사합니다
제 생각에는
현재 쿼리에서 불필요한 부분들을 제거해 나가기 보다는
필요한 부분만을 가지고 처음부터 새로 작성하는 것을 추천합니다.