반응형
SQL을 짜다 보면 차집합 로직을 구사하기 위해 NOT IN 구문을 사용하게 되는데...
이놈의 NOT IN 서브쿼리라는 것이.. 무조건 FULL SCAN을 하기 땜시 극악의 성능을 보이는 지라..
가급적이면 피해가고 싶은 것이 사실이다.
- SELECT *
- FROM TAB_A
- WHERE IP_ADDR NOT IN
- (SELECT MANAGEMENTIP FROM TAB_B)
(7818개 행 적용됨)
'Worktable' 테이블. 스캔 수 7819, 논리적 읽기 수 7825, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_B' 테이블. 스캔 수 1, 논리적 읽기 수 1, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_A' 테이블. 스캔 수 1, 논리적 읽기 수 201, 물리적 읽기 수 0, 미리 읽기 수 0.
SQL Server 실행 시간:
CPU 시간 = 109ms, 경과 시간 = 1057ms.
'Worktable' 테이블. 스캔 수 7819, 논리적 읽기 수 7825, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_B' 테이블. 스캔 수 1, 논리적 읽기 수 1, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_A' 테이블. 스캔 수 1, 논리적 읽기 수 201, 물리적 읽기 수 0, 미리 읽기 수 0.
SQL Server 실행 시간:
CPU 시간 = 109ms, 경과 시간 = 1057ms.
위와 같은 구문은 다음과 같이 NOT EXISTS 구문으로 대체될 수 있다.
- SELECT *
- FROM TAB_A
- WHERE NOT EXISTS
- (SELECT * FROM TAB_B WHERE TAB_B.MANAGEMENTIP = TAB_A.IP_ADDR)
(7818개 행 적용됨)
'TAB_A' 테이블. 스캔 수 1, 논리적 읽기 수 201, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_B' 테이블. 스캔 수 1, 논리적 읽기 수 1, 물리적 읽기 수 0, 미리 읽기 수 0.
SQL Server 실행 시간:
CPU 시간 = 172ms, 경과 시간 = 682ms.
'TAB_A' 테이블. 스캔 수 1, 논리적 읽기 수 201, 물리적 읽기 수 0, 미리 읽기 수 0.
'TAB_B' 테이블. 스캔 수 1, 논리적 읽기 수 1, 물리적 읽기 수 0, 미리 읽기 수 0.
SQL Server 실행 시간:
CPU 시간 = 172ms, 경과 시간 = 682ms.
아래의 구문 역시 퍼포먼스 적인 면에서는 피하라고 권장되는 이른바 "상관관계 서브쿼리(Correlated Subquery)" 문이라 차라리 위에 것이 나을 것 같기도 하고... 그래도 인덱스를 탈 수 있으니까 아래 것이 나을 것 같기도 하고.. ^^;;
과연 얼마나 효과가 있을까?
위의 테스트 결과 상으로는 실행시간상으로는 퍼포먼스 향상 효과가 2배 정도 밖에(?) 안되는 것 같지만, "논리적 읽기" 부분을 보면 훨씬 큰 차이가 있다는 것을 알 수 있다.
반응형
'연구개발 > SQL2005' 카테고리의 다른 글
악성 쿼리 찾아내기(2) - ClearTrace (0) | 2009.06.27 |
---|---|
악성 쿼리 찾아내기(1) - ReadTrace (0) | 2009.06.27 |
배치작업으로 TABLE을 동기화 할 때 주의사항 (0) | 2009.06.27 |
테이블에 블로킹이 풀리지 않을 때의 응급조치방법 (0) | 2009.06.27 |
INSTEAD OF 트리거 (0) | 2009.06.27 |