MSSQL2005 부터 생긴 Cross Apply 조인
아직 많은 테스트가 필요하지만 적당한 Index가 있을 경우 처리할 데이터를 상당히 줄여줘 성능 향상에 도움이 된다
(다른 경우도 마찬가지지만 더욱 큰 폭으로)
특히 해당 유저의 최근 기록 같은 류의 정보를 추출할 때 기존 방식의 경우 이를 다시 Self Join 하거나
문자열 조작으로 처리하곤 했는데
Self Join 의 경우 테이블을 두번 읽게 되고 문자열 조작의 경우 그 구문이 상당히 길어질 뿐더러 복잡해서 쉽게 사용 하기 힘들다
더군다나 SQL의 경우 (C, C++, C#, Java, 등등의)프로그램 랭귀지들 보다 문자열 처리에 느린 편이다
하지만 Cross Apply의 경우 비교적 간단한 구문으로 빠르고 유용하게 사용 할 수 있다
이는 유지보수도 쉬워서 내가 아닌 다른 사람이 주석 없이도 내용 파악이 쉽고 그만큼 실수를 할 가능성도 줄어듬을 의미한다.
조심할 점은 Nested Loop Join으로 풀어 나가니 대용량 처리에는 부적합 하고 이런 저런 테스트를 꼭 해봐야 한다는 것!
--기존방식 SELECT a.UID, b.RegDate FROM dbo.[User] AS a WITH(NOLOCK) INNER JOIN ( SELECT a.UID, MAX(a.RegDate) AS RegDate FROM dbo.[UserLoginLog] AS a WITH(NOLOCK) GROUP BY a.UID ) AS b ON a.UID = b.UID --Cross Apply SELECT a.UID, b.RegDate FROM dbo.[User] AS a WITH(NOLOCK) CROSS APPLY ( SELECT TOP 1 b.UID, b.RegDate FROM dbo.[UserLoginLog] AS b WITH(NOLOCK) WHERE a.UID = b.UID ORDER BY RegDate DESC ) AS b
위의 실행 결과 비교는 다음과 같다
테스트용 데이터 이기 때문에 데이터 량이 적지만 실제 서버의 엄청난 데이터를 생각한다면 그 차이는 더더욱 클 것이라 생각된다.
ps1. Apply 구문에는 Cross Apply와 Outer Apply가 존재 하며
이 차이는 Inner Join과 Left Outer Join혹은 Right Outer Join과 동일함
CREATE DATABASE TEST; GO USE TEST; GO CREATE TABLE dbo.[User] ( UID int ,Name varchar(10) ,CONSTRAINT PK_User_UID PRIMARY KEY(UID) ); CREATE TABLE dbo.[UserLoginLog] ( UID int ,RegDate datetime ,CONSTRAINT FK_UserLoginLog_User_UID FOREIGN KEY(UID) REFERENCES dbo.[User](UID) ); CREATE UNIQUE CLUSTERED INDEX UIDX_UserLoginLog_UID_RegDate ON dbo.[UserLoginLog](UID, RegDate); GO INSERT INTO dbo.[User](UID, Name) VALUES(1, '가나다'); INSERT INTO dbo.[User](UID, Name) VALUES(2, '라마바'); INSERT INTO dbo.[User](UID, Name) VALUES(3, '사아자'); INSERT INTO dbo.[User](UID, Name) VALUES(4, '차카타'); GO INSERT INTO dbo.[UserLoginLog](UID, RegDate) SELECT ROW_NUMBER() OVER(ORDER BY a.OBJECT_ID) % 4 + 1 AS UID, DATEADD(SS, ROW_NUMBER() OVER(ORDER BY a.OBJECT_ID), GETDATE()) AS RegDate FROM sys.objects AS a CROSS JOIN sys.objects AS b; GO
'프로그래밍 > MSSQL\정보' 카테고리의 다른 글
[MSSQL] Parallel과 Sort 가 동시에 있을 때 발생하는 문제 (0) | 2012.10.05 |
---|---|
[MSSQL] sqlcmd 응용 (0) | 2012.05.28 |
[MSSQL] Identity 컬럼 입력(SET IDENTITY_INSERT) (0) | 2012.05.10 |
[MSSQL] 정규식으로 특수문자 유무(문자열 패턴) 검사 (0) | 2012.05.04 |
[MSSQL] 원하는 순서로 정렬된 Identity 컬럼 추가 (0) | 2012.04.24 |