MSSQL Cross Apply 사용
Cross Apply 라고 들어보셨나요? 조금 생소한 예약어들인데요.
MSSQL에서만 존재한다고 합니다. Inner join 이나 서브쿼리가 필요한 경우에 사용하면 속도 향상을 할 수 있다는 장점이 있다고 합니다.
하여 오늘은 MSSQL Cross Apply 사용에 대해서 알아보겠습니다.
어느 회사에서 상품을 팔고 있습니다. 상품이 판매될 때마다 상품판매 테이블에 정보를 담습니다. 상품판매 테이블의 구성은 상품코드, 가격, 날짜 입니다.
어느날 사장님이 날짜별로 판매된 상품을 보고싶은데, 전일 대비 증감도 같이 보고 싶다고 하십니다. 그래서 개발자가 열심히 쿼리를 작성합니다. (데이터는 약 5,000건 입니다.)
1. 서브쿼리
SELECT
A.상품코드, A.날짜, A.가격
, A.가격 - (
SELECT
TOP 1 B.가격
FROM 상품판매테이블 B
WHERE A.상품코드 = B.상품코드
AND A.날짜 < B.날짜
ORDER BY B.날짜 DESC) AS 증감
)
FROM 상품판매테이블 A
실행시간은 약 8초 입니다.
2. Join and 서브쿼리
SELECT
A.상품코드, A.날짜, A.가격
, B.날짜, B.가격
, A.가격 - B.가격 AS 증감
FROM 상품판매테이블 A
INNER JOIN 상품판매테이블 B
ON A.상품코드 = B.상품코드
WHERE A.날짜 > B.날짜
AND B.날짜 = (SELECT TOP 1 날짜
FROM 상품판매테이블 C
WHERE C.상품코드 = A.상품코드 AND C.날짜 < A.날짜 ORDER BY 날짜 DESC)
실행시간은 약 2초
3. Cross Apply
SELECT
ROW_NUMBER() OVER( ORDER BY A.PRJT_CD) AS NUM
, rtrim(A.PRJT_CD) as PRJT_CD -- 프로젝트 코드
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_P)) AS AC370_P
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_F)) AS AC370_F
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_A)) AS AC370_A
, CONVERT(VARCHAR, G.MR_TTL) AS MR_TTL
, CONVERT(VARCHAR, G.MR_KEY_TTL) AS MR_KEY_TTL
FROM TB_PRJT_INFO AS A with(nolock)
LEFT OUTER JOIN dbo.BASECODE AS B with(nolock) ON A.PRJT_FNSH_CD = B.TOTAL_CODE
LEFT OUTER JOIN dbo.TB_PRJT_SCH1 AS C with(nolock) ON A.PRJT_CD = C.PSPID -- 프로젝트 스케쥴 정보
--LEFT OUTER JOIN @RESULTS_PS AS D ON A.PRJT_CD = D.PRJT_CD -- 프로젝트 Procurement Progress[Monthly] > PS[Act / Plan]
--LEFT OUTER JOIN @RESULTS_MD AS E ON A.PRJT_CD = E.PRJT_CD -- 프로젝트 Procurement Progress[Monthly] > MD[Act / Plan]
-- INNER JOIN FFN_PCPS_ALL_PRJT(@PRJT_CD, @USER_ID) AS F ON A.PRJT_CD = F.PRJT_CD -- 프로젝트 조건이 없을 경우 사용자의 모든 프로젝트 정보를 보여 줘야 하기 때문에 JOIN
INNER JOIN FFN_PCPS_ALL_PRJT(@PRJT_CD, @USER_ID) AS F ON A.PRJT_CD = F.PRJT_CD -- 프로젝트 조건이 없을 경우 사용자의 모든 프로젝트 정보를 보여 줘야 하기 때문에 JOIN
CROSS APPLY FFN_PCPS_PREX1000(F.PRJT_CD, CONVERT(VARCHAR(10), GETDATE(), 120)) AS G
이상으로 MSSQL Cross Apply 사용에 대해서 알아보았습니다.
오늘도 행복한 하루 되세요.
MSSQL에서만 존재한다고 합니다. Inner join 이나 서브쿼리가 필요한 경우에 사용하면 속도 향상을 할 수 있다는 장점이 있다고 합니다.
하여 오늘은 MSSQL Cross Apply 사용에 대해서 알아보겠습니다.
어느 회사에서 상품을 팔고 있습니다. 상품이 판매될 때마다 상품판매 테이블에 정보를 담습니다. 상품판매 테이블의 구성은 상품코드, 가격, 날짜 입니다.
어느날 사장님이 날짜별로 판매된 상품을 보고싶은데, 전일 대비 증감도 같이 보고 싶다고 하십니다. 그래서 개발자가 열심히 쿼리를 작성합니다. (데이터는 약 5,000건 입니다.)
1. 서브쿼리
SELECT
A.상품코드, A.날짜, A.가격
, A.가격 - (
SELECT
TOP 1 B.가격
FROM 상품판매테이블 B
WHERE A.상품코드 = B.상품코드
AND A.날짜 < B.날짜
ORDER BY B.날짜 DESC) AS 증감
)
FROM 상품판매테이블 A
실행시간은 약 8초 입니다.
2. Join and 서브쿼리
SELECT
A.상품코드, A.날짜, A.가격
, B.날짜, B.가격
, A.가격 - B.가격 AS 증감
FROM 상품판매테이블 A
INNER JOIN 상품판매테이블 B
ON A.상품코드 = B.상품코드
WHERE A.날짜 > B.날짜
AND B.날짜 = (SELECT TOP 1 날짜
FROM 상품판매테이블 C
WHERE C.상품코드 = A.상품코드 AND C.날짜 < A.날짜 ORDER BY 날짜 DESC)
실행시간은 약 2초
3. Cross Apply
SELECT A.상품코드, A.날자, A.가격, C.날짜, C.가격, A.가격 - C.가격 AS 증감
FROM 상품판매테이블 A
FROM 상품판매테이블 A
CROSS APPLY (SELECT TOP 1 * FROM 상품판매테이블 B
WHERE B.상품코드 = A.상품코드
AND B.날짜 < A.날짜
ORDER BY 날짜 DESC) C
실행시간은 약 1초
Cross Apply를 사용하는것이 속도 향상에는 좋습니다.
단, CPU를 많이 사용하여 서버 자원을 많이 사용한다는 점이 단점이라고 할 수 있습니다.
또한, Outer Apply는 Outer Join과 사용이 비슷합니다.
또한 Cross Apply는 조인과 같이 조인되는 필드를 토대로 함수에서 값을 가져와 기냥 붙여준다.
SELECT
ROW_NUMBER() OVER( ORDER BY A.PRJT_CD) AS NUM
, rtrim(A.PRJT_CD) as PRJT_CD -- 프로젝트 코드
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_P)) AS AC370_P
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_F)) AS AC370_F
, CONVERT(VARCHAR, CONVERT(DECIMAL(18, 1), G.AC370_A)) AS AC370_A
, CONVERT(VARCHAR, G.MR_TTL) AS MR_TTL
, CONVERT(VARCHAR, G.MR_KEY_TTL) AS MR_KEY_TTL
FROM TB_PRJT_INFO AS A with(nolock)
LEFT OUTER JOIN dbo.BASECODE AS B with(nolock) ON A.PRJT_FNSH_CD = B.TOTAL_CODE
LEFT OUTER JOIN dbo.TB_PRJT_SCH1 AS C with(nolock) ON A.PRJT_CD = C.PSPID -- 프로젝트 스케쥴 정보
--LEFT OUTER JOIN @RESULTS_PS AS D ON A.PRJT_CD = D.PRJT_CD -- 프로젝트 Procurement Progress[Monthly] > PS[Act / Plan]
--LEFT OUTER JOIN @RESULTS_MD AS E ON A.PRJT_CD = E.PRJT_CD -- 프로젝트 Procurement Progress[Monthly] > MD[Act / Plan]
-- INNER JOIN FFN_PCPS_ALL_PRJT(@PRJT_CD, @USER_ID) AS F ON A.PRJT_CD = F.PRJT_CD -- 프로젝트 조건이 없을 경우 사용자의 모든 프로젝트 정보를 보여 줘야 하기 때문에 JOIN
INNER JOIN FFN_PCPS_ALL_PRJT(@PRJT_CD, @USER_ID) AS F ON A.PRJT_CD = F.PRJT_CD -- 프로젝트 조건이 없을 경우 사용자의 모든 프로젝트 정보를 보여 줘야 하기 때문에 JOIN
CROSS APPLY FFN_PCPS_PREX1000(F.PRJT_CD, CONVERT(VARCHAR(10), GETDATE(), 120)) AS G
이상으로 MSSQL Cross Apply 사용에 대해서 알아보았습니다.
오늘도 행복한 하루 되세요.
댓글
댓글 쓰기