02. (성능) 스칼라 함수를 SELECT절이나 WHERE절에 썻을 경우 성능 저하
다음과 같은 쿼리가 있다
SELECT resoc_id
FROM t_n_mem
WHERE 1 = 1
AND resoc_id = '0493019000940'
AND mem_nm = '홍길동'
and JOIN_MEM_DT = dbo.FN_GETDT(GETDATE())
위에 컬럼들에 인덱스가 잘 걸려있다고 가정해보자. 하지만 실제 실행 시간은 매우 오래 걸린다.
이유는 실제 SQL Server 실행 절차와 우리가 예상하는 실행 절차가 틀리기 때문이다.
우리가 예상하는 실행 절차
1. dbo.FN_GETDT는 날짜를 입력받아 YYYYMMDD 형태의 문자열을 리턴하는 함수이니
현재 시간을 입력받아 1번 실행되어 문자열을 리턴
2. 리턴된 YYYYMMDD 문자열을 이용해 JOIN_MEM_DT 의 인덱스를 검색한다.
실제 실행 절차
1. FN_GETDT 는 스칼라 함수임을 알고 SQL 서버는 T_N_MEM의 레코드수만큼 FN_GETDT를 실행하고
2. 이렇게 리턴받은 문자열을 매번 JOIN_MEM_DT와 비교한다.
이 차이는 스칼라 함수일 경우 100% 존재한다. 그렇기 때문에 WHERE절에 스칼라 함수를 쓰는것은 항상 피해야 한다. SELECT절에 넣는다면 WHERE절에서 걸려서 나온 ROW수만큼 실행되는것으로 그나마 괜찮은 성능을 보여주기도 하지만..
해결방법
1. 스칼라 함수를 확정적 함수로 바꾸어주면 될수도 있다. (가능성이 있다는 말이다. 항상 되지는 않음). 먼말인지는 조회좀 해보자. 안중요해서 패스
2. 테이블형태반환 함수로 바꾼다. 이 경우는 우리가 원하는 것만큼 딱 1번 실행된다.
SELECT resoc_id
FROM t_n_mem
WHERE 1 = 1
AND resoc_id = '0493019000940'
AND mem_nm = '홍길동'
and JOIN_MEM_DT = (SELECT * FROM dbo.FN_GETDT(GETDATE()))