select top 10 * from orders

118
select top 10 * from orders where orderid not in (select top 10 orderid from orders order by orderid asc) select top 10 * from dbo.orders o where not exists (select * from (select top 10 orderid from dbo.orders order by orderid asc) dv where dv.orderid = o.orderid ) select * from dbo.orders o join (select top 10 orderid from (select top 840 orderid from dbo.orders order by orderid asc) dv order by orderid desc) dv on o.orderid = dv.orderid select top 10 * from dbo.orders where orderid > (select max(orderid) from (select top 10 orderid from dbo.orders SQL Server 2000 SQL Server 2000 실실 실실 실실 실실 실실 실실 김김김 김김김 Microsoft SQL Server MVP Microsoft SQL Server MVP [email protected] [email protected] SQL Server SQL Server 김김 김김 김김 김김 김김 김김 SDS MultiCampus SDS MultiCampus 김김김김 김김김김 www.sdscampus.co.kr www.sdscampus.co.kr

Upload: mikayla-maldonado

Post on 30-Dec-2015

60 views

Category:

Documents


11 download

DESCRIPTION

SQL Server 2000 실행 계획 읽기 김정선 Microsoft SQL Server MVP [email protected] SQL Server 기술 지원 삼성 SDS MultiCampus 전임강사 www.sdscampus.co.kr. select top 10 * from orders where orderid not in (select top 10 orderid from ordersorder by orderid asc) select top 10 * from dbo.orders o - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: select top 10 * from orders

select top 10 *from orderswhere orderid not in (select top 10 orderid from orders

order by orderid asc)

select top 10 *from dbo.orders owhere not exists (select * from (select top 10 orderid from dbo.orders order by orderid asc) dv where dv.orderid = o.orderid )

select * from dbo.orders o join (select top 10 orderid from (select top 840 orderid from dbo.orders order by orderid asc) dv order by orderid desc) dvon o.orderid = dv.orderid

select top 10 *from dbo.orderswhere orderid > (select max(orderid)

from (select top 10 orderid from dbo.orders

order by orderid asc) dv)

SQL Server 2000SQL Server 2000실행 계획 읽기실행 계획 읽기

김정선김정선Microsoft SQL Server MVPMicrosoft SQL Server [email protected]@unitel.co.kr

SQL Server SQL Server 기술 지원기술 지원삼성삼성 SDS MultiCampus SDS MultiCampus 전임강사전임강사www.sdscampus.co.krwww.sdscampus.co.kr

Page 2: select top 10 * from orders

2

목표목표

SQL Server 2000SQL Server 2000 의 의 Query Query 실행 계획 이해실행 계획 이해 SQL Server SQL Server 집합 및 관계 연산에 대한 이해집합 및 관계 연산에 대한 이해 쿼리 분석 및 최적화 기본 접근 방법으로 활용쿼리 분석 및 최적화 기본 접근 방법으로 활용 비용 기반 최적화 기본 개념 이해비용 기반 최적화 기본 개념 이해

Page 3: select top 10 * from orders

3

목차목차

실행 계획 소개실행 계획 소개 실행 계획 읽기실행 계획 읽기 Non-SARG (Non-SARG ( 비 검색인수비 검색인수 ) ) 사례 분석사례 분석

Page 4: select top 10 * from orders

4

다루지 않는 내용들다루지 않는 내용들

기본적인 연산자들만 다룸기본적인 연산자들만 다룸 병렬 계획병렬 계획 , , 커서커서 , , 등은 제외등은 제외

튜닝이 목적은 아님튜닝이 목적은 아님 접근 방법에 대한 소개가 목적접근 방법에 대한 소개가 목적

예제 예제 DBDB NorthwindNorthwind

Clustered Index Clustered Index 기반 기반 PKPK 와 기타 인덱스를 보유와 기타 인덱스를 보유 EPlanEPlan

Clustered Index Clustered Index 기반 기반 PKPK 만 보유만 보유 EPlanHeapEPlanHeap

Nonclustered Index Nonclustered Index 기반 기반 PKPK 만 보유만 보유 TempTemp

INSERT, UPDATE, DELETE INSERT, UPDATE, DELETE 예제용으로 예제용으로 Demo Demo 에서 직접 생성에서 직접 생성

Page 5: select top 10 * from orders

5

대상 및 선수 지식대상 및 선수 지식

MOC 2073 MOC 2073 과정 이수자과정 이수자 , , “Programming(Implementing)“Programming(Implementing) a Microsoft SQL a Microsoft SQL Server 2000 Database”Server 2000 Database”

현업 개발자 및 관리자현업 개발자 및 관리자 실행 계획 읽기에 관심 있는 개발자실행 계획 읽기에 관심 있는 개발자 쿼리 분석 및 최적화에 관심 있는 개발자쿼리 분석 및 최적화에 관심 있는 개발자

확인확인 . . 실행 계획 읽기에 대한 학습 경험이 없다실행 계획 읽기에 대한 학습 경험이 없다 ?? 없다면없다면 , , 인덱스에 대한 학습 경험이 없다인덱스에 대한 학습 경험이 없다 ??

Page 6: select top 10 * from orders

6

Module 1. Module 1. 실행 계획 소개실행 계획 소개

현실 세계 실행 계획현실 세계 실행 계획 통계 정보통계 정보 비용 기반 비용 기반 Query OptimizerQuery Optimizer 실행 계획 소개실행 계획 소개 인덱스 복습인덱스 복습 PAGE I/O PAGE I/O 읽기읽기

Page 7: select top 10 * from orders

7

현실 세계의 실행 계획현실 세계의 실행 계획 -1-1

Query: 서울에서 부산까지 가세요 !

시간시간 : 1: 1 시간시간비용비용 : 66,500: 66,500원원

시간시간 : 4.5: 4.5 시간시간비용비용 : 37,000: 37,000원원

시간시간 : 5+?: 5+?시간시간비용비용 : 28,200: 28,200원원

시간시간 : ? : ? 시간시간비용비용 : ? + : ? + 병원비병원비

실행 계획Query Optimizer 의 기본 역할

실행 계획Query Optimizer 의 기본 역할

Page 8: select top 10 * from orders

8

현실 세계의 실행 계획현실 세계의 실행 계획 -2-2

교통 인프라교통 인프라 Clustered Index, Nonclustered Index, HeapClustered Index, Nonclustered Index, Heap

교통편교통편 Index Seek, Index Scan, Table ScanIndex Seek, Index Scan, Table Scan

시간시간 쿼리 실행 시간 쿼리 실행 시간 (( 구문 분석구문 분석 , , 컴파일컴파일 , , 실행실행 )) 응답 시간응답 시간

비용비용 시스템 자원 사용량시스템 자원 사용량 CPU, IO, Memory(Cache), Network CPU, IO, Memory(Cache), Network 등등

Page 9: select top 10 * from orders

9

우리가 할 일우리가 할 일

충분한 인프라와 교통편 제공충분한 인프라와 교통편 제공 자전거로 자전거로 11 시간 내에 도착하기를 바란다시간 내에 도착하기를 바란다 ??

충분한 비용 제공충분한 비용 제공 20,000 20,000 원 짜리 비행기원 짜리 비행기 ??

정확한 정보 제공 정확한 정보 제공 (( 통계 정보통계 정보 )) 거리가 얼마인가거리가 얼마인가 ?? 각 교통편의 비용은 얼마인가각 교통편의 비용은 얼마인가 ??

결과 확인 및 조정결과 확인 및 조정 Query Optimizer Query Optimizer 의 선택은 무엇인가의 선택은 무엇인가 ?? 그 선택은 적절한가그 선택은 적절한가 ??

Page 10: select top 10 * from orders

10

통계 정보통계 정보

통계정보 통계정보 (Statistics)(Statistics) 칼럼 값에 대한 분포 단계칼럼 값에 대한 분포 단계 및 기타 정보 등으로 구성및 기타 정보 등으로 구성 컬럼 값 전체나 또는 샘플링으로 처리컬럼 값 전체나 또는 샘플링으로 처리 sysindexes.statblob sysindexes.statblob (image (image 타입타입 )) 에 저장 에 저장

쿼리 최적화에 사용되는 가장 중요한 기초 정보쿼리 최적화에 사용되는 가장 중요한 기초 정보 배포 통계 표시배포 통계 표시

DBCC SHOW_STATISTICS(DBCC SHOW_STATISTICS(table, targettable, target))

대상대상 자동 생성자동 생성

인덱스 칼럼인덱스 칼럼 SARG SARG 대상 칼럼 대상 칼럼 (WHERE (WHERE 절절 , JOIN , JOIN 절절 ))

수동 생성 가능수동 생성 가능

Page 11: select top 10 * from orders

11

Query OptimizerQuery Optimizer

목적목적 최적 실행 계획을 생성최적 실행 계획을 생성 통계 정보의 자동 생성 및 업데이트통계 정보의 자동 생성 및 업데이트

내용내용 각 테이블에서 어떤 인덱스를 사용할 것인가각 테이블에서 어떤 인덱스를 사용할 것인가 ?? 어떤 조인 전략과 조인 순서를 사용할 것인가어떤 조인 전략과 조인 순서를 사용할 것인가 ?? 내부 정렬을 수행할 것인가내부 정렬을 수행할 것인가 ?? 중간 결과 집합을 저장하기 위해서 내부 작업테이블중간 결과 집합을 저장하기 위해서 내부 작업테이블 (worktable)(worktable)

를 생성할 것인가를 생성할 것인가 ?? 다중 프로세스상에서 쿼리를 실행할 것인가다중 프로세스상에서 쿼리를 실행할 것인가 ??

Page 12: select top 10 * from orders

12

비용 기반 최적화비용 기반 최적화

비용 비용 = I/O = I/O 와 와 CPU CPU 비용비용 최적화 방법최적화 방법

가능한 실행 계획들의 예측 비용을 평가가능한 실행 계획들의 예측 비용을 평가 가장 적은 예측 비용을 선택가장 적은 예측 비용을 선택

비용 예측 정확도 비용 예측 정확도 = = 통계정보 정확도통계정보 정확도 I/O I/O 와 와 CPU CPU 자원 사용을 최소화자원 사용을 최소화

반환되는 행 수의 최소화반환되는 행 수의 최소화 페이지 읽기 수의 최소화페이지 읽기 수의 최소화 물리적 연산자 종류물리적 연산자 종류 연산 순서연산 순서

Page 13: select top 10 * from orders

13

실행 계획 소개실행 계획 소개

실행 계획 소개실행 계획 소개 실행 계획 종류실행 계획 종류 실행 계획 출력 방법실행 계획 출력 방법 그래픽 실행 계획 읽기그래픽 실행 계획 읽기 Connection Option Connection Option 보기보기 Profiler Profiler 보기보기

Page 14: select top 10 * from orders

14

실행 계획을 보세요실행 계획을 보세요……

일반적인 질문들일반적인 질문들

subquery subquery 가 빠른지가 빠른지… … join join 이 빠른지이 빠른지… … 어떤 경우에 그런가요어떤 경우에 그런가요 ??무슨 차이 때문에 그런가요무슨 차이 때문에 그런가요 ? ? 그럼그럼 , , 수고하세요수고하세요subquery subquery 가 빠른지가 빠른지… … join join 이 빠른지이 빠른지… … 어떤 경우에 그런가요어떤 경우에 그런가요 ??무슨 차이 때문에 그런가요무슨 차이 때문에 그런가요 ? ? 그럼그럼 , , 수고하세요수고하세요

조건 식에서 조건 식에서 between between 과 과 in in 절 중 어느 쪽이 더 나은가요절 중 어느 쪽이 더 나은가요 ??조건 식에서 조건 식에서 between between 과 과 in in 절 중 어느 쪽이 더 나은가요절 중 어느 쪽이 더 나은가요 ??

왜 왜 FROM FROM 절에 조인과 절에 조인과 WHERE WHERE 절 조인의 결과가 다른가요절 조인의 결과가 다른가요 ??왜 왜 FROM FROM 절에 조인과 절에 조인과 WHERE WHERE 절 조인의 결과가 다른가요절 조인의 결과가 다른가요 ??

파생 테이블파생 테이블 (derive table, inline view) (derive table, inline view) 를 사용하면 성능이 향상되나요를 사용하면 성능이 향상되나요 ??파생 테이블파생 테이블 (derive table, inline view) (derive table, inline view) 를 사용하면 성능이 향상되나요를 사용하면 성능이 향상되나요 ??

2 2 개의 쿼리 중에 어느 것이 더 빠르고 자원을 적게 먹으면서 수행되는지 개의 쿼리 중에 어느 것이 더 빠르고 자원을 적게 먹으면서 수행되는지 비교하고 싶습니다비교하고 싶습니다 . . 어떤 방법이 좋을까요어떤 방법이 좋을까요 ??2 2 개의 쿼리 중에 어느 것이 더 빠르고 자원을 적게 먹으면서 수행되는지 개의 쿼리 중에 어느 것이 더 빠르고 자원을 적게 먹으면서 수행되는지 비교하고 싶습니다비교하고 싶습니다 . . 어떤 방법이 좋을까요어떤 방법이 좋을까요 ??

FROM FROM 절에 작성한 테이블의 위치가 성능에 영향을 주나요절에 작성한 테이블의 위치가 성능에 영향을 주나요 ??FROM FROM 절에 작성한 테이블의 위치가 성능에 영향을 주나요절에 작성한 테이블의 위치가 성능에 영향을 주나요 ??

조건 식에 상수를 사용한 경우와 변수를 사용한 경우에 왜 성능에 차이가 있나요조건 식에 상수를 사용한 경우와 변수를 사용한 경우에 왜 성능에 차이가 있나요 ??조건 식에 상수를 사용한 경우와 변수를 사용한 경우에 왜 성능에 차이가 있나요조건 식에 상수를 사용한 경우와 변수를 사용한 경우에 왜 성능에 차이가 있나요 ??

ORDER BY ORDER BY 절을 사용하지 않아도 정렬이 되게 할 수 없나요절을 사용하지 않아도 정렬이 되게 할 수 없나요 ??ORDER BY ORDER BY 절을 사용하지 않아도 정렬이 되게 할 수 없나요절을 사용하지 않아도 정렬이 되게 할 수 없나요 ??

COUNT(*) COUNT(*) 를 사용하는데 인덱스를 만들면 성능 향상이 되나요를 사용하는데 인덱스를 만들면 성능 향상이 되나요 ??COUNT(*) COUNT(*) 를 사용하는데 인덱스를 만들면 성능 향상이 되나요를 사용하는데 인덱스를 만들면 성능 향상이 되나요 ??

Page 15: select top 10 * from orders

15

실행 계획 소개실행 계획 소개

실행 계획실행 계획 (Execution Plan) (Execution Plan) 또는 또는 쿼리 계획쿼리 계획 (Query Plan) (Query Plan) 이라고 언급이라고 언급

SQL Server SQL Server 쿼리 처리 방법에 대한 출력쿼리 처리 방법에 대한 출력 각각의 각각의 논리적 연산자논리적 연산자 및 및 물리적 연산자물리적 연산자 연산 순서연산 순서 예측 및 실제 예측 및 실제 비용비용 ((CPU, I/O, CPU, I/O, 메모리메모리 , , 등등 ))

Query OptimizerQuery Optimizer 의 최종 산출물의 최종 산출물 Hint Hint 를 통한 강제 지정이 가능를 통한 강제 지정이 가능

Page 16: select top 10 * from orders

16

실행 계획 읽기의 목적실행 계획 읽기의 목적

쿼리 처리 방법 확인 쿼리 처리 방법 확인 쿼리 분석쿼리 분석 , , 최적화 그리고 튜닝 기초 자료최적화 그리고 튜닝 기초 자료

연산자연산자 , , 연산 순서 및 비용 확인연산 순서 및 비용 확인 Query Optimizer Query Optimizer 실행 계획의 타당성 검증실행 계획의 타당성 검증 DB, Table, Index, StatisticsDB, Table, Index, Statistics 등의 튜닝등의 튜닝 보다 나은 실행 계획을 위한 쿼리 최적화보다 나은 실행 계획을 위한 쿼리 최적화 필요할 경우 실행 계획 조정필요할 경우 실행 계획 조정

R-DBMS, Query Optimizer R-DBMS, Query Optimizer 에 대한 이해에 도움에 대한 이해에 도움 ““Reading showplan output Reading showplan output is as muchis as much an art an art as it isas it is a science a science””, ,

by Kalen Delaneyby Kalen Delaney

Page 17: select top 10 * from orders

17

실행 계획의 종류실행 계획의 종류

예상 실행 계획예상 실행 계획 쿼리를 실행하지 않고쿼리를 실행하지 않고 , , 예상 실행 계획 표시예상 실행 계획 표시 통계 정보에 기반통계 정보에 기반 , , 예상 값만을 출력예상 값만을 출력

실제 실행 계획과 차이실제 실행 계획과 차이 DemoDemo, , ““ 변수를 사용한 경우 왜 달라지나요변수를 사용한 경우 왜 달라지나요 ?”?”

쿼리 실행에 따른 부하가 없다쿼리 실행에 따른 부하가 없다 실행 계획실행 계획

쿼리 실행과 함께쿼리 실행과 함께 , , 실행 시점의 실행 계획 표시실행 시점의 실행 계획 표시 보다 정확한 실행 계획 출력보다 정확한 실행 계획 출력 쿼리 실행에 따른 부하가 있다쿼리 실행에 따른 부하가 있다

비교비교 예상 실행 계획에서 볼 수 있는 내용예상 실행 계획에서 볼 수 있는 내용

FASTFIRSTROW, (FAST n) FASTFIRSTROW, (FAST n) 힌트힌트 , SET , SET 문문 , etc…, etc… 실행 계획에서 볼 수 있는 내용실행 계획에서 볼 수 있는 내용

임시 테이블을 포함한 저장 프로시저임시 테이블을 포함한 저장 프로시저 , etc…, etc…

Page 18: select top 10 * from orders

18

실행 계획의 출력 방법실행 계획의 출력 방법

쿼리 분석기의 그래픽 실행 계획쿼리 분석기의 그래픽 실행 계획 Connection(Session) OptionConnection(Session) Option 프로필러프로필러 (Profiler)(Profiler)

Page 19: select top 10 * from orders

19

그래픽 실행 계획 보기그래픽 실행 계획 보기

쿼리 메뉴쿼리 메뉴 예상 실행 계획표시 예상 실행 계획표시 (Ctrl-L)(Ctrl-L)

SET SHOWPLAN_TEXT OFFSET SHOWPLAN_TEXT OFF SET SHOWPLAN_ALL ON/OFFSET SHOWPLAN_ALL ON/OFF 메뉴 실행 시 출력메뉴 실행 시 출력

실행 계획 표시 실행 계획 표시 (Ctrl-K)(Ctrl-K) SET STATISTICS PROFILE ON/OFFSET STATISTICS PROFILE ON/OFF 메뉴 실행 시 활성화메뉴 실행 시 활성화 , , 쿼리 실행 시 출력쿼리 실행 시 출력

Page 20: select top 10 * from orders

20

그래픽 실행계획 출력 요소그래픽 실행계획 출력 요소

쿼리 비용쿼리 비용

쿼리 텍스트쿼리 텍스트

노드노드 (( 부모부모 //자식자식 ))

물리적물리적 // 논리적 논리적 연산자연산자

연산 비용연산 비용

Sequence of Steps

Page 21: select top 10 * from orders

21

물리적물리적 // 논리적 연산자논리적 연산자

쿼리 및 업데이트 실행 방식을 설명쿼리 및 업데이트 실행 방식을 설명 물리적 연산자물리적 연산자

물리적 구현 알고리즘물리적 구현 알고리즘Clustered Index SeekClustered Index SeekNested LoopNested Loop JoinJoinStream Aggregate, etcStream Aggregate, etc

논리적 연산자논리적 연산자 관계형 대수 연산관계형 대수 연산 쿼리 자체에 포함된 구문과 연관쿼리 자체에 포함된 구문과 연관

Inner JoinInner JoinAggregate, etcAggregate, etc

참고참고 . . 온라인 설명서온라인 설명서 , , 색인색인 , , 키워드 키워드 - - ““ 실행 계획 표시실행 계획 표시””

Page 22: select top 10 * from orders

22

그래픽 실행계획 출력 읽기그래픽 실행계획 출력 읽기

읽는 순서읽는 순서 위에서 아래로위에서 아래로 , , 오른쪽에서 왼쪽으로오른쪽에서 왼쪽으로

일괄 처리 총 비용 대비 각 쿼리 비용일괄 처리 총 비용 대비 각 쿼리 비용 각 노드는 각 노드는

논리 및 물리 연산자 아이콘을 표시논리 및 물리 연산자 아이콘을 표시 부모 노드와 관련부모 노드와 관련 형제 노드들은 동일한 열에서 생성형제 노드들은 동일한 열에서 생성 , , 화살표를 통한 표시화살표를 통한 표시

트리 구조는 실행되는 명령문의 유형에 의해 결정트리 구조는 실행되는 명령문의 유형에 의해 결정 Transact-SQL Transact-SQL 및 저장 프로시저및 저장 프로시저 DML, DML, 트리거트리거 관계 연산자관계 연산자 DECLARE CURSORDECLARE CURSOR

Page 23: select top 10 * from orders

23

그래픽 실행 계획 도구 설명 정보그래픽 실행 계획 도구 설명 정보

물리적 연산자 물리적 연산자 ** 물리 연산자물리 연산자 , Stream Aggregate, Nested Loop Join, etc, Stream Aggregate, Nested Loop Join, etc

논리적 연산자논리적 연산자 물리 연산자에 해당하는 논리 연산자물리 연산자에 해당하는 논리 연산자 , , 서로 다를 경우 서로 다를 경우 (( / / ) ) 로 구분로 구분

행 개수행 개수 연산자에 의해 출력된 행 수연산자에 의해 출력된 행 수

예상 행 크기예상 행 크기 연산자에 의해 출력된 예상 행 크기연산자에 의해 출력된 예상 행 크기

I/O I/O 비용비용 연산자에 대한 모든 연산자에 대한 모든 I/O I/O 작업의 예상 비용작업의 예상 비용

CPU CPU 비용비용 연산자에 대한 연산자에 대한 CPU CPU 작업의 예상 비용작업의 예상 비용

실행 횟수실행 횟수 쿼리 중 연산이 실행되는 횟수쿼리 중 연산이 실행되는 횟수

연산 실행에 대한 연산 실행에 대한 Query OptimizerQuery Optimizer 의 비용 의 비용 (( 쿼리 총 비용에 대한 쿼리 총 비용에 대한 비율비율 ))

하위 트리 비용하위 트리 비용 이 연산 및 모든 자식 연산들에 대한 누적 비용이 연산 및 모든 자식 연산들에 대한 누적 비용

인수인수 쿼리 에서 사용하는 조건자와 매개변수 쿼리 에서 사용하는 조건자와 매개변수 (Argument)(Argument)

비용비용

* * 빨간색빨간색으로 표시된으로 표시된 물리적 연산자 물리적 연산자는는 Query OptimizerQuery Optimizer 에 의해서 에 의해서 손실된 열 통계손실된 열 통계 또는 또는 손실된 조인 조건자 손실된 조인 조건자 와 같은 경고를 발생했음을 나타냄와 같은 경고를 발생했음을 나타냄 . (. ( 개별 주제로 소개됨개별 주제로 소개됨 ))

Page 24: select top 10 * from orders

24

실행 계획 비용실행 계획 비용

‘‘ 문서화되지 않은문서화되지 않은 정보정보’’ 실제 실제 I/O I/O 양이나 양이나 CPU CPU 사이클은 아님사이클은 아님

별도의 도구를 사용별도의 도구를 사용 내부 비용 알고리즘에 의해 책정된 값 내부 비용 알고리즘에 의해 책정된 값 예측 쿼리 비용이며예측 쿼리 비용이며 , , 실제 실행 시간으로 변환되지 실제 실행 시간으로 변환되지

않는다않는다 OptimizerOptimizer 의 판단 근거를 알 수 있는 기초 자료의 판단 근거를 알 수 있는 기초 자료

쿼리 비용의 크기를 체감하기 위한 방법으로 유용쿼리 비용의 크기를 체감하기 위한 방법으로 유용SQL Server MagazineSQL Server Magazine, , by Brian Moranby Brian Moran

추가 자료추가 자료 참조참조 SQL Server Quantitative Performance AnalysisSQL Server Quantitative Performance Analysis

Joe Chang, Joe Chang, www.sql-server-performance.comwww.sql-server-performance.com

Page 25: select top 10 * from orders

25

Connection Option Connection Option 보기보기

예상 실행 계획 표시예상 실행 계획 표시 SHOWPLAN_ALL ON/OFFSHOWPLAN_ALL ON/OFF

출력출력 : : 실행 계획에 대한 모든 정보실행 계획에 대한 모든 정보 SHOWPLAN_TEXT ON/OFFSHOWPLAN_TEXT ON/OFF

출력출력 : StmtText : StmtText 항목항목 (( 쿼리쿼리 , , 연산자연산자 , , 인수인수 )) 두 옵션은 배타적으로 사용두 옵션은 배타적으로 사용

실행 계획 표시실행 계획 표시 SET PROFILE ON/OFFSET PROFILE ON/OFF

출력출력 : SHOWPLAN_ALL : SHOWPLAN_ALL 출력출력 + ROWS, EXECUTES+ ROWS, EXECUTES

Page 26: select top 10 * from orders

26

Connection Option Connection Option 출력출력

StmtTextStmtText Transact-SQL Transact-SQL 문의 텍스트문의 텍스트 , , 작업에 대한 설명작업에 대한 설명 , , 연산자연산자

StmtIdStmtId 현재 일괄 처리에 있는 명령문의 수 현재 일괄 처리에 있는 명령문의 수 (* (* 명령문의 명령문의 ID)ID)

NodeIDNodeID 현재 노드의 현재 노드의 IDID

ParentParent 부모 노드의 부모 노드의 IDID

PhysicalOp, LogicalOp, ArgumentPhysicalOp, LogicalOp, Argument

연산자가 사용하는 값에 대해 쉼표로 구분된 목록연산자가 사용하는 값에 대해 쉼표로 구분된 목록 . . 계산된 식계산된 식 (( 예예 , , SELECT SELECT 목록이나 목록이나 WHERE WHERE 절에 있는절에 있는 )) 이나 이 쿼리를 처리하기 이나 이 쿼리를 처리하기 위해 쿼리 프로세스에서 사용한 내부 값 등위해 쿼리 프로세스에서 사용한 내부 값 등

EstimateRows, EstimateIO, EstimateCPUEstimateRows, EstimateIO, EstimateCPU

DefinedValueDefinedValue

AvgRowSize, TotalSubtreeCostAvgRowSize, TotalSubtreeCost

OutputListOutputList 현재 작업에서 예상하고 있는 열에 대한 쉼표로 구분된 목록현재 작업에서 예상하고 있는 열에 대한 쉼표로 구분된 목록

WarningsWarnings 현재 작업과 관련된 경고 메시지에 대한 쉼표로 구분된 목록현재 작업과 관련된 경고 메시지에 대한 쉼표로 구분된 목록

TypeType 노드 유형노드 유형 . . 쿼리의 부모 노드는 유형이 쿼리의 부모 노드는 유형이 T-SQL T-SQL 문 유형문 유형 (( 예예 : SELECT, : SELECT, INSERT, EXECUTE) INSERT, EXECUTE) 등이며등이며 , , 실행 계획을 나타내는 하위 노드에 실행 계획을 나타내는 하위 노드에 대해서는 대해서는 PLAN_ROW PLAN_ROW 유형유형 . . 노드 유형에 따라서 위 출력 내용이 노드 유형에 따라서 위 출력 내용이 달라짐달라짐

ParallelParallel 1 = 1 = 연산자가 병렬로 실행연산자가 병렬로 실행 , 0 = , 0 = 직렬 실행직렬 실행

EstimateExecutionsEstimateExecutions 쿼리를 실행하는 동안 연산자가 실행될 횟수쿼리를 실행하는 동안 연산자가 실행될 횟수

Page 27: select top 10 * from orders

27

프로필러프로필러 (Profiler) (Profiler) 보기보기

이벤트 클래스이벤트 클래스 성능성능

Execution PlanExecution Plan Show Plan AllShow Plan All Show Plan StatisticsShow Plan Statistics Show Plan TextShow Plan Text

데이터 열데이터 열 BinaryDataBinaryData EventClassEventClass IntegerDataIntegerData ObjectIDObjectID TextDataTextData

Page 28: select top 10 * from orders

28

손실된 통계 정보손실된 통계 정보

빨간색으로 표시된빨간색으로 표시된물리적 연산자물리적 연산자

통계 정보가 없는 경우통계 정보가 없는 경우

데이터베이스 옵션데이터베이스 옵션ALTER DATABASE NorthwindALTER DATABASE Northwind

SET AUTO_CREATE_STATISTICS OFFSET AUTO_CREATE_STATISTICS OFF

Page 29: select top 10 * from orders

29

인덱스 복습인덱스 복습

Page Page 구조구조 HeapHeap B-Tree IndexB-Tree Index

Nonclustered IndexNonclustered Index Clustered IndexClustered Index NC Index with CL IndexNC Index with CL Index

Page I/O Page I/O 읽기읽기

Page 30: select top 10 * from orders

30

Page Page 구조구조

Record #1Record #1

Record #2Record #2

Record #3Record #3

pageId=(1:205), type, objId,…pageId=(1:205), type, objId,…

0x1d20x1d2 0x1220x122 0x600x60

Page HeaderPage Header(96 byte)(96 byte)

Data Rows Data Rows

Row Offset Row Offset

데이터 저장소 기본 단위데이터 저장소 기본 단위 8K 8K 고정 크기고정 크기 유형유형

DataData IndexIndex Text/ImageText/Image IAMIAM PFS, GAM, SGAMPFS, GAM, SGAM 기타기타……

ExtentExtent 테이블과 인덱스의 공간 테이블과 인덱스의 공간

할당 단위할당 단위 연속된 연속된 8 page8 page

Page 31: select top 10 * from orders

31

HeapHeap

Northwind.dbo.OrderDetails Northwind.dbo.OrderDetails 테이블테이블

OrderID DESC, ProductID ASC (UQ, NC Index)OrderID DESC, ProductID ASC (UQ, NC Index) UnitPriceUnitPrice QuantityQuantity DiscountDiscount

CL Index CL Index 가 없는 테이블의 가 없는 테이블의 Data Page(s)Data Page(s) 데이터 행이 저장되는 특정 순서가 없다데이터 행이 저장되는 특정 순서가 없다 연결된 리스트로 연결되어 있지 않다연결된 리스트로 연결되어 있지 않다 ..

HeapHeap11077 311077 3 ……....

10743 4610743 46 ……....

10912 2910912 29 ……....

… ….... ……....

11077 411077 4 ……....

10912 2910912 29 ……....

10742 7210742 72 ……....

… ….... ……....

10912 1110912 11 ……....

11077 611077 6 ……....

10741 210741 2 ……....

… ….... ……....

10792 210792 2 ……....

10742 6010742 60 ……....

10913 5810913 58 ……....

… ….... ……....

1:3761:376 1:377 1:378 1:379

10575 7210575 72 …….... 10575 7610575 76 …….... 10754 3310754 33 …….... 10574 4010574 40 ……....

10911 110911 1 ……....

10676 4410676 44 ……....

11077 711077 7 ……....

… ….... ……....

1:380

10742 310742 3 ……....… … ......

Page 32: select top 10 * from orders

32

Leaf LevelLeaf Level(Level = 0)(Level = 0)

Non-Leaf LevelNon-Leaf Level(Level = 1)(Level = 1)

ROOTROOT(Level = 2)(Level = 2)

Sorted Sorted BookmarkBookmarkKeyValue KeyValue

KeyValueKeyValue Page-Pointer Page-Pointer

KeyValueKeyValue Page-Pointer Page-Pointer

B(alanced)-Tree IndexB(alanced)-Tree Index

HeapHeapKey1 Key2Key1 Key2 Col3 Col4 Col5 Col3 Col4 Col5

Page 33: select top 10 * from orders

33

Nonclustered IndexNonclustered Index

Leaf LevelLeaf Level NULL 1:380:02211077 3 1:376:00011077 411077 6

… … ......

….

10913 58 1:379:00210912 11 1:378:00010912 2910911 1….

1:377:0011:380:000….

1:377:0001:378:001….

10743 46 1:376:00110742 3 1:380:00310742 6010742 72….

1:379:0011:377:002….

10575 72 1:376:00310575 76 1:377:00310754 3310574 40….

1:378:0031:379:003….

1:408 1:410 1:412 1:413

Non-Leaf Non-Leaf LevelLevel

NULL 1:40810913 58 1:41010743 46

… ….... ……....

10575 7210417 68

1:4121:4131:414

ROOTROOT

HeapHeap11077 3 …..

10743 46 …..

10912 29 …..

….. …..

11077 4 …..

10912 29 …..

10742 72 …..

….. …..

10912 11 …..

11077 6 …..

10741 2 …..

….. …..

10792 2 …..

10742 60 …..

10913 58 …..

….. …..

1:376 1:377 1:378 1:379

10575 72 ….. 10575 76 ….. 10754 33 ….. 10574 40 …..

10911 1 …..

10676 44 …..

11077 7 …..

….. …..

1:380

10742 3 ….. … … ......

KeyValueKeyValue BookmarkBookmark

Page 34: select top 10 * from orders

34

NULL 1:40810913 58 1:41010743 46

… ….... ……....

10575 7210417 68

1:4121:4131:414

NULL 1:43210981 38 1:43410869 1

… ….... ……....

10768 3110670 46

1:4351:4361:437

Non-Leaf Non-Leaf LevelLevel

ROOTROOT

Leaf Level = Data Page = Index PageLeaf Level = Data Page = Index Page Data Row Data Row 가 논리적으로 정렬된 구조를 가진다가 논리적으로 정렬된 구조를 가진다 Leaf Level Page Leaf Level Page 에 에 Bookmark Bookmark 값을 포함하지 않는다값을 포함하지 않는다

Clustered IndexClustered Index

Leaf LevelLeaf Level

… … ......

1:408 1:410 1:412 1:413

NULL 1:380:02211077 3 1:376:00011077 411077 6….

10913 58 1:379:00210912 11 1:378:00010912 2910911 1….

1:377:0011:380:000….

1:377:0001:378:001….

10743 46 1:376:00110742 3 1:380:00310742 6010742 72….

1:379:0011:377:002….

10575 72 1:376:00310575 76 1:377:00310754 3310574 40….

1:378:0031:379:003….

Data PagesData Pages 11077 2 …..

11077 3 …..

11077 4 …..

….. …..

10981 38 …..

10980 75 …..

10979 7 …..

….. …..

10869 1 …..

10869 11 …..

10869 23 …..

….. …..

10768 31 …..

10768 60 …..

10768 71 …..

….. …..

1:432 1:434 1:435 1:436

11077 6 ….. 10979 12 ….. 10869 68 ….. 10767 42 …..

10670 46 …..

10676 67 …..

10670 73 …..

….. …..

1:437

10670 75 ….. … … ......

Page 35: select top 10 * from orders

35

Data PagesData Pages

CL Non-Leaf CL Non-Leaf LevelLevel

NULL 1:43210981 3810981 38 1:43410869 1 … ….... ……....

1:435

NC Index with CL IndexNC Index with CL Index

… … ......11077 2 …..

11077 3 …..

11077 4 ….. ….. …..

10981 3810981 38 …..

10980 75 …..

10979 7 ….. ….. …..

10869 1 …..

10869 11 …..

10869 23 ….. ….. …..

10768 31 …..

10768 60 …..

10768 71 ….. ….. …..

1:432 1:434 1:435 1:436

10670 46 …..

10676 67 …..

10670 73 ….. ….. …..

1:437

ROOTROOT

NULL NULL263.5000 10981 3810981 38263.5000

… … ......….

10964 38….

1:360 1:362 1:364 1:365

35.1000 10402 63 35.1000 10376 63 35.1000….

10324 63….

21.5000 10847 71 21.5000 10771 71 21.5000….

10768 71….

16.8000 10251 65 16.8000 10250 65 16.2500….

11072 50….

NC Non-Leaf NC Non-Leaf LevelLevel

(KeyValue = UnitPrice)(KeyValue = UnitPrice)ROOTROOT

NULL 1:36035.1000 10402 63 1:36221.5000 10847 71….

1:364….

Leaf LevelLeaf LevelKeyValueKeyValue BookmarkBookmark

Page 36: select top 10 * from orders

36

Page I/O Page I/O 읽기읽기

쿼리 별 쿼리 별 Page I/O Page I/O 읽기읽기SET STATISTICS IO ONSET STATISTICS IO ON

……‘‘Emp' Emp' 테이블테이블 . . 스캔 수스캔 수 1, 1, 논리적 읽기 수논리적 읽기 수 1, 1, 물리적 읽기 수 물리적 읽기 수 0, 0, 미리 읽기 수 미리 읽기 수 0.0.

테이블테이블 // 인덱스 페이지 사용량인덱스 페이지 사용량 검색검색

SELECTSELECT id, indid, id, indid, dpagesdpages, , usedused, root, firstIAM, *, root, firstIAM, * FROM sysindexes FROM sysindexes

idid : object id : object idindidindid : index id (0: Heap, 1: CL Index, 2~250: NC Index or : index id (0: Heap, 1: CL Index, 2~250: NC Index or 통계정보통계정보 , 255: (B)Lob, 255: (B)Lob

dpagesdpages : 1) indid (0, 1): data pages, 2) indid (2~250): leaf level pages : 1) indid (0, 1): data pages, 2) indid (2~250): leaf level pagesusedused : 1) indid (0, 1): table pages, 2) indid (2~250): index pages : 1) indid (0, 1): table pages, 2) indid (2~250): index pages

Page 37: select top 10 * from orders

37

Module 2. Module 2. 실행 계획 읽기실행 계획 읽기

INSERT, UPDATE, DELETEINSERT, UPDATE, DELETE SELECTSELECT

데이터 검색 방법데이터 검색 방법 SELECT select_listSELECT select_list WHERE search_conditionWHERE search_condition ORDER BYORDER BY 집계 함수와 집계 함수와 GROUP BY GROUP BY JOINJOIN UNIONUNION DERIVED TABLEDERIVED TABLE SUBQUERYSUBQUERY

Page 38: select top 10 * from orders

38

Table InsertTable Insert

도구 설명도구 설명 입력 행을 지정된 테이블에 삽입입력 행을 지정된 테이블에 삽입

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 각 열의 설정 값각 열의 설정 값 , SET:(), SET:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

Data PagesData Pages NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건 제약조건

CHECK CHECK 제약조건제약조건

Page 39: select top 10 * from orders

39

도구 설명도구 설명 클러스터된 인덱스에 행을 삽입클러스터된 인덱스에 행을 삽입

인수 인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 각 열의 설정 값각 열의 설정 값 . SET:(). SET:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

CL Index PagesCL Index Pages NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건제약조건

CHECK CHECK 제약조건제약조건

Clustered Index InsertClustered Index Insert

Page 40: select top 10 * from orders

40

Table UpdateTable Update

도구 설명도구 설명 지정한 테이블의 입력 행을 업데이트지정한 테이블의 입력 행을 업데이트

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 업데이트 열의 설정 값업데이트 열의 설정 값 . SET:(). SET:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건제약조건

CHECK CHECK 제약조건제약조건 DEFINE:(), WHERE:() DEFINE:(), WHERE:() 조건자를 별도 처리조건자를 별도 처리

Index SeekIndex Seek Table ScanTable Scan

Page 41: select top 10 * from orders

41

Clustered Index UpdateClustered Index Update

도구 설명도구 설명 클러스터된 인덱스에 행을 업데이트클러스터된 인덱스에 행을 업데이트

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 업데이트 열의 설정 값업데이트 열의 설정 값 . SET:(). SET:() 연산자가 정의하는 값연산자가 정의하는 값 , DEFINE:() , DEFINE:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

CL Index PagesCL Index Pages NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건제약조건

CHECK CHECK 제약조건제약조건

Page 42: select top 10 * from orders

42

Table DeleteTable Delete

도구 설명도구 설명 지정한 테이블의 입력 행을 업데이트지정한 테이블의 입력 행을 업데이트

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건제약조건

WHERE:() WHERE:() 조건자를 별도 처리조건자를 별도 처리 Index SeekIndex Seek Table ScanTable Scan

Page 43: select top 10 * from orders

43

Clustered Index DeleteClustered Index Delete

도구 설명도구 설명 클러스터된 인덱스에서 행 삭제클러스터된 인덱스에서 행 삭제

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

CL Index PagesCL Index Pages NC Index PagesNC Index Pages PK, UNIQUE PK, UNIQUE 제약조건제약조건 FK FK 제약조건제약조건

Page 44: select top 10 * from orders

44

데이터 검색 방법데이터 검색 방법

Table ScanTable Scan Index Seek/ScanIndex Seek/Scan Bookmark LookupBookmark Lookup Clustered Index Seek/ScanClustered Index Seek/Scan Covering IndexCovering Index

Page 45: select top 10 * from orders

45

Table Scan (Heap)Table Scan (Heap)

도구 설명도구 설명 테이블에서 행을 스캔테이블에서 행을 스캔

인수인수 적용 개체적용 개체 , OBJECT:(), OBJECT:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:()

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = Data = Data 페이지 총 수페이지 총 수 CPU CPU 집중적집중적

모든 행모든 행

Page 46: select top 10 * from orders

46

Index Seek (Heap)Index Seek (Heap)

도구 설명도구 설명 클러스터되지 않은 인덱스에서 특정 범위의 클러스터되지 않은 인덱스에서 특정 범위의

행을 행을 검색검색 인수인수

적용 개체적용 개체 , OBJECT:(), OBJECT:() 인덱스 사용 검색 조건 식인덱스 사용 검색 조건 식 , SEEK:(), SEEK:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:() 출력 순서 유지출력 순서 유지 , ORDERED , ORDERED 절절

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = Non-Leaf Level = Non-Leaf Level 수 수 + Leaf + Leaf 페이지 수페이지 수 * * **Leaf Leaf 페이지 수 페이지 수 = = 검색 행 수 검색 행 수 / Leaf / Leaf 페이지 당 행 수페이지 당 행 수

CPUCPU 검색 행 수검색 행 수

Page 47: select top 10 * from orders

47

도구 설명도구 설명 클러스터되지 않은 인덱스를 전체 또는 클러스터되지 않은 인덱스를 전체 또는

한 범위만한 범위만 스캔스캔 인수인수

적용 개체적용 개체 , OBJECT:(), OBJECT:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:() 출력 순서 유지출력 순서 유지 , ORDERED , ORDERED 절절

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = Non-Leaf Level = Non-Leaf Level 수 수 + Leaf + Leaf 페이지 총 수페이지 총 수 CPU CPU 집중적집중적

검색 행 수검색 행 수

Index ScanIndex Scan

Page 48: select top 10 * from orders

48

Bookmark Lookup (Heap)Bookmark Lookup (Heap)

도구 설명도구 설명 책갈피책갈피 ((RIDRID 또는 클러스터링 키또는 클러스터링 키 )) 를 사용를 사용 , ,

테이블 또는 클러스터된 인덱스의테이블 또는 클러스터된 인덱스의 해당해당행 조회행 조회

인수인수 책갈피책갈피 , BOOKMARK:(), BOOKMARK:() 적용 개체적용 개체 , OBJECT:(), OBJECT:() 미리 읽기 사용미리 읽기 사용 , WITH PREFETCH, WITH PREFETCH

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = = 행 개수행 개수

Page 49: select top 10 * from orders

49

도구 설명도구 설명 클러스터된 인덱스에서 특정 범위의 클러스터된 인덱스에서 특정 범위의

행을 행을 검색검색 인수인수

적용 개체적용 개체 , OBJECT:(), OBJECT:() 인덱스 사용 검색 조건 식인덱스 사용 검색 조건 식 , SEEK:(), SEEK:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:() 출력 순서 유지출력 순서 유지 , ORDERED , ORDERED 절절

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = Non-Leaf Level = Non-Leaf Level 수 수 + Data + Data 페이지 수페이지 수 * * **Data Data 페이지 수 페이지 수 = = 검색 행 수 검색 행 수 / Data / Data 페이지 당 행 수페이지 당 행 수

CPUCPU 검색 행 수검색 행 수

Clustered Index SeekClustered Index Seek

Page 50: select top 10 * from orders

50

도구 설명도구 설명 클러스터된 인덱스를 전체 또는 클러스터된 인덱스를 전체 또는

한 범위를한 범위를 스캔스캔 인수인수

적용 개체적용 개체 , OBJECT:(), OBJECT:() 검색 조건 식검색 조건 식 , WHERE:(), WHERE:() 출력 순서 유지출력 순서 유지 , ORDERED , ORDERED 절절

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = Non-Leaf Level = Non-Leaf Level 수 수 + Data + Data 페이지 총 수페이지 총 수 CPU CPU 집중적집중적

검색 행 수검색 행 수

Clustered Index Scan Clustered Index Scan

Page 51: select top 10 * from orders

51

도구 설명도구 설명 책갈피책갈피 (RID (RID 또는 또는 클러스터링 키클러스터링 키 )) 를 사용를 사용 , ,

테이블 또는 클러스터된 인덱스의테이블 또는 클러스터된 인덱스의 해당해당행 조회행 조회

인수인수 책갈피책갈피 , BOOKMARK:(), BOOKMARK:() 적용 개체적용 개체 , OBJECT:(), OBJECT:() 미리 읽기 사용미리 읽기 사용 , WITH PREFETCH, WITH PREFETCH

비용 소비자비용 소비자 I/O I/O 집중적집중적

논리적 읽기 수 논리적 읽기 수 = SUM(= SUM( 개별 행 별 개별 행 별 Lookup I/O)Lookup I/O)

Bookmark Lookup (CL Index)Bookmark Lookup (CL Index)

Page 52: select top 10 * from orders

52

Bookmark Lookup Bookmark Lookup 정리 정리 - 1- 1

BookmarkBookmark 위치위치

Nonclustered IndexNonclustered Index,, LeafLeaf 페이지페이지 종류종류

Heap Heap 기반기반 : : RowIDRowID (8byte) (8byte) CL Index CL Index 기반기반 : : CL KeyCL Key (= (= 길이길이 ))

Bookmark LookupBookmark Lookup QueryQuery 에서 요구하는 칼럼 들을 반환하는데 에서 요구하는 칼럼 들을 반환하는데 NC IndexNC Index

Leaf Leaf 페이지에 저장된 페이지에 저장된 Data(Key + Bookmark) Data(Key + Bookmark) 만으로 만으로 불충분한 경우에 추가되는 연산자불충분한 경우에 추가되는 연산자

검색 행 수만큼 반복 수행되는 연산검색 행 수만큼 반복 수행되는 연산 가장 가장 IO IO 집중적인 연산 중의 하나집중적인 연산 중의 하나 ↑↑검색 행 수 검색 행 수 = ↑= ↑ 연산 횟수 연산 횟수 = ↓Lookup = ↓Lookup 성능 성능 = ↓NC Index = ↓NC Index 성능성능

Page 53: select top 10 * from orders

53

Bookmark Lookup Bookmark Lookup 정리 정리 - 2- 2

NC Index Seek → Bookmark Lookup I/O NC Index Seek → Bookmark Lookup I/O 계산계산 Heap Heap 기반기반

논리적 읽기 수 논리적 읽기 수 = (Non-Leaf Level = (Non-Leaf Level 수 수 + Leaf + Leaf 페이지 수페이지 수 ) + ) + 행 개수행 개수 = (1 + 1) + 5 = 7 pages= (1 + 1) + 5 = 7 pages = (1 + 1) + 10 = 12 pages = (1 + 1) + 10 = 12 pages = (1 + 1) + 20 = 22 pages = (1 + 1) + 20 = 22 pages … …

CL Index CL Index 기반기반논리적 읽기 수 논리적 읽기 수 = Non-Leaf Level = Non-Leaf Level 수 수 + Leaf + Leaf 페이지 수 페이지 수 + SUM(+ SUM( 개별 행 별 개별 행 별 Lookup I/O) Lookup I/O) = (1 + 1) + (2 * 5) = 12 pages= (1 + 1) + (2 * 5) = 12 pages = (1 + 1) + (2 * 10) = 22 pages = (1 + 1) + (2 * 10) = 22 pages = (1 + 1) + (2 * 20) = 42 pages = (1 + 1) + (2 * 20) = 42 pages … …

NC NC 인덱스의 사용 여부를 결정하는 중요 요소인덱스의 사용 여부를 결정하는 중요 요소 성능 문제가 있는 경우 성능 문제가 있는 경우 LookupLookup 을 수행하지 않은 인덱스 고려을 수행하지 않은 인덱스 고려 ,,

Covering IndexCovering Index (a.k.a. Covered Index), (a.k.a. Covered Index), Covered QueryCovered Query

Page 54: select top 10 * from orders

54

Index (PK, OrderID + ProductID)Index (PK, OrderID + ProductID)Index (PK, OrderID + ProductID)Index (PK, OrderID + ProductID)

Covering Index (Heap)Covering Index (Heap)

SELECT SELECT OrderID, ProductIDOrderID, ProductID, Quantity, QuantityFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE OrderID < 10251WHERE OrderID < 10251

SELECT SELECT OrderID, ProductIDOrderID, ProductID, Quantity, QuantityFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE OrderID < 10251WHERE OrderID < 10251

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE OrderID < 10251WHERE OrderID < 10251

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE OrderID < 10251WHERE OrderID < 10251

SELECT SELECT COUNT(*)COUNT(*)FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]

SELECT SELECT COUNT(*)COUNT(*)FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]

SELECT SELECT ProductIDProductID, , COUNT(*)COUNT(*)FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]GROUP BY GROUP BY ProductIDProductID

SELECT SELECT ProductIDProductID, , COUNT(*)COUNT(*)FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]GROUP BY GROUP BY ProductIDProductID

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE ProductID = 41WHERE ProductID = 41

SELECT SELECT OrderID, ProductIDOrderID, ProductIDFROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE ProductID = 41WHERE ProductID = 41

추가 추가 DemoDemo추가 추가 DemoDemo

Page 55: select top 10 * from orders

55

Covering Index (CL Index)Covering Index (CL Index)

Clustered Index (PK, OrderID), Index (OrderDate)Clustered Index (PK, OrderID), Index (OrderDate)Clustered Index (PK, OrderID), Index (OrderDate)Clustered Index (PK, OrderID), Index (OrderDate)

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersWHERE OrderDate = '19970101'WHERE OrderDate = '19970101'

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersWHERE OrderDate = '19970101'WHERE OrderDate = '19970101'

SELECT OrderID, OrderDateSELECT OrderID, OrderDateFROM OrdersFROM OrdersWHERE OrderDate = '19970101'WHERE OrderDate = '19970101'

SELECT OrderID, OrderDateSELECT OrderID, OrderDateFROM OrdersFROM OrdersWHERE OrderDate = '19970101'WHERE OrderDate = '19970101'

Page 56: select top 10 * from orders

56

Clustered Index (PK, OrderID ASC)Clustered Index (PK, OrderID ASC)Clustered Index (PK, OrderID ASC)Clustered Index (PK, OrderID ASC)

Ordered Ordered 절절

인덱스에 의해 정렬되는 순서로 인덱스에 의해 정렬되는 순서로 반환되도록 쿼리 프로세스가 결정반환되도록 쿼리 프로세스가 결정 ORDERED FORWARDORDERED FORWARD ORDERED BACKWARDORDERED BACKWARD

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersORDER BY ORDER BY OrderIDOrderID ASCASC

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersORDER BY ORDER BY OrderIDOrderID ASCASC

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersORDER BY ORDER BY OrderIDOrderID DESCDESC

SELECT OrderID, OrderDate, EmployeeIDSELECT OrderID, OrderDate, EmployeeIDFROM OrdersFROM OrdersORDER BY ORDER BY OrderIDOrderID DESCDESC

Page 57: select top 10 * from orders

57

SELECT select_listSELECT select_list

Compute ScalarCompute Scalar DistinctDistinct TopTop

참고참고 . . 이제부터 이제부터 SQL SQL 구문 위주로 연산자를 분석구문 위주로 연산자를 분석

Page 58: select top 10 * from orders

58

도구 설명도구 설명 식을 계산하여 계산된 식을 계산하여 계산된 스칼라 값을 생성스칼라 값을 생성

(BOL)(BOL) 인수인수

계산 식계산 식 , DEFINE: (), DEFINE: () 비용 소비자비용 소비자

CPU CPU 집중적집중적 행 개수행 개수

관련 연산자관련 연산자 select-list select-list 수식수식 집계 함수집계 함수 BLOB BLOB 데이터 처리데이터 처리 (text, ntext, image)(text, ntext, image)

Compute ScalarCompute Scalar

Page 59: select top 10 * from orders

59

참조참조 . . 해당 연산자해당 연산자 ((Aggregate, SortAggregate, Sort) ) 참조참조

Hash Match/AggregateHash Match/AggregateHash Match/AggregateHash Match/Aggregate

Sort/Distinct SortSort/Distinct SortSort/Distinct SortSort/Distinct Sort

Stream Aggregate/AggregateStream Aggregate/AggregateStream Aggregate/AggregateStream Aggregate/Aggregate

DistinctDistinct

SELECT SELECT DISTINCTDISTINCT OrderDate OrderDateFROM OrdersFROM Orders

SELECT SELECT DISTINCTDISTINCT OrderDate OrderDateFROM OrdersFROM Orders

SELECT SELECT DISTINCTDISTINCT Productid ProductidFROM EPlan..[Order Details]FROM EPlan..[Order Details]

SELECT SELECT DISTINCTDISTINCT Productid ProductidFROM EPlan..[Order Details]FROM EPlan..[Order Details]

SELECT SELECT DISTINCTDISTINCT EmployeeID, OrderDateEmployeeID, OrderDateFROM OrdersFROM Orders

SELECT SELECT DISTINCTDISTINCT EmployeeID, OrderDateEmployeeID, OrderDateFROM OrdersFROM Orders

Page 60: select top 10 * from orders

60

도구 설명도구 설명 정렬 순서를 기준으로 처음 몇 행 또는 행 비율 정렬 순서를 기준으로 처음 몇 행 또는 행 비율

반환반환 업데이트 계획에서도 행 개수 제한을 위해 사용업데이트 계획에서도 행 개수 제한을 위해 사용

인수인수 TIE TIE 검사 열 목록검사 열 목록 , TIE COLUMNS: (), TIE COLUMNS: ()

비용 소비자비용 소비자 적은 적은 CPU CPU 비용비용

행 개수행 개수

TopTop

Page 61: select top 10 * from orders

61

도구 설명도구 설명 입력을 정렬입력을 정렬 TopN TopN 작업을 위한 특수 연산작업을 위한 특수 연산

인수인수 TOP TOP 개수개수 졍렬될 열 목록졍렬될 열 목록 , ORDER BY: (), ORDER BY: () 졍렬 기준졍렬 기준 , {ASC | DESC}, {ASC | DESC}

비용 소비자비용 소비자 I/O I/O 집중적집중적

페이지 수페이지 수 CPU CPU 집중적집중적

행 개수행 개수

참조참조 . . 독립적인 독립적인 Sort Sort →→ Top Top 연산도 가능연산도 가능

Sort /TopN SortSort /TopN Sort

Page 62: select top 10 * from orders

62

Top vs. SET ROWCOUNTTop vs. SET ROWCOUNT

SELECT TOP 10 OrderDate, OrderIDSELECT TOP 10 OrderDate, OrderIDFROM OrdersFROM OrdersWHERE OrderID > 10248WHERE OrderID > 10248ORDER BY ORDER BY OrderIDOrderID DESC DESC

SELECT TOP 10 OrderDate, OrderIDSELECT TOP 10 OrderDate, OrderIDFROM OrdersFROM OrdersWHERE OrderID > 10248WHERE OrderID > 10248ORDER BY ORDER BY OrderIDOrderID DESC DESC

SET ROWCOUNT 10SET ROWCOUNT 10 SELECT OrderDate, OrderIDSELECT OrderDate, OrderID FROM OrdersFROM Orders WHERE OrderID > 10248WHERE OrderID > 10248 ORDER BY ORDER BY OrderIDOrderID DESC DESCSET ROWCOUNT 0SET ROWCOUNT 0

SET ROWCOUNT 10SET ROWCOUNT 10 SELECT OrderDate, OrderIDSELECT OrderDate, OrderID FROM OrdersFROM Orders WHERE OrderID > 10248WHERE OrderID > 10248 ORDER BY ORDER BY OrderIDOrderID DESC DESCSET ROWCOUNT 0SET ROWCOUNT 0

SET ROWCOUNT 500SET ROWCOUNT 500 SELECT Orderid, Productid, QuantitySELECT Orderid, Productid, Quantity FROM OrderDetailsFROM OrderDetails ORDER BY ORDER BY QuantityQuantity DESC DESCSET ROWCOUNT 0SET ROWCOUNT 0

SELECT TOP 500 Orderid, Productid, QuantitySELECT TOP 500 Orderid, Productid, QuantityFROM OrderDetailsFROM OrderDetailsORDER BY ORDER BY QuantityQuantity DESC DESC

Page 63: select top 10 * from orders

63

WHERE <search_condition>WHERE <search_condition>

WHERE <search_condition>WHERE <search_condition> FilterFilter Auto-ParameterizationAuto-Parameterization BETWEENBETWEEN LIKELIKE EXISTS vs. COUNT(*)EXISTS vs. COUNT(*) NOTNOT AND vs. ORAND vs. OR Index InterchangeIndex Interchange Union IndexUnion Index IN IN 사례사례

Page 64: select top 10 * from orders

64

WHERE <search_condition>WHERE <search_condition>

<search_condition><search_condition> 논리 연산자 논리 연산자 AND, OR AND, OR 및 및 NOTNOT 을 사용을 사용 , , 하나 이상의 조건자를 결합하나 이상의 조건자를 결합 조건자 조건자 (Predicate)(Predicate)

WHERE WHERE 절절 , HAVING , HAVING 절의 검색 조건절의 검색 조건 , FROM , FROM 절의 조인 조건에 절의 조인 조건에 사용사용

TRUE, FALSE TRUE, FALSE 또는 또는 UNKNOWNUNKNOWN 으로 평가되는 식으로 평가되는 식 비교 연산자비교 연산자 , , 논리 연산자논리 연산자 BETWEEN, LIKE, EXISTS, IN, ALL, ANY, BETWEEN, LIKE, EXISTS, IN, ALL, ANY, 등등

관련 실행 계획 연산자관련 실행 계획 연산자 [Clustered] Index Seek/Scan, Table Scan [Clustered] Index Seek/Scan, Table Scan 연산자의 인수 부분연산자의 인수 부분

SEEK: ()SEEK: () WHERE: ()WHERE: ()

Filter Filter 연산자연산자

Page 65: select top 10 * from orders

65

도구 설명도구 설명 조건자를 기준으로 행 집합을 제한조건자를 기준으로 행 집합을 제한

인수인수 조건자조건자 (( 필터 식필터 식 ), WHERE: ()), WHERE: ()

비용 소비자비용 소비자 적은 적은 CPUCPU

행 개수행 개수

FilterFilter

Page 66: select top 10 * from orders

66

Filter: WHERE(EmployeeID = @2)Filter: WHERE(EmployeeID = @2)Filter: WHERE(EmployeeID = @2)Filter: WHERE(EmployeeID = @2)

Index (OrderID DESC + ProductID)Index (OrderID DESC + ProductID)Index (OrderID DESC + ProductID)Index (OrderID DESC + ProductID)

WHERE <search_condition> WHERE <search_condition> 사례사례

SELECT *SELECT *FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE WHERE OrderIDOrderID == 10250 10250

AND Productid < 50AND Productid < 50

SELECT *SELECT *FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE WHERE OrderIDOrderID == 10250 10250

AND Productid < 50AND Productid < 50

SELECT *SELECT *FROM EPlanHeap..OrdersFROM EPlanHeap..OrdersWHERE OrderID < 10250WHERE OrderID < 10250

AND AND EmployeeID = 5EmployeeID = 5

SELECT *SELECT *FROM EPlanHeap..OrdersFROM EPlanHeap..OrdersWHERE OrderID < 10250WHERE OrderID < 10250

AND AND EmployeeID = 5EmployeeID = 5

SELECT *SELECT *FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE WHERE OrderID <OrderID < 10250 10250

AND Productid < 50 AND Productid < 50

SELECT *SELECT *FROM EPlanHeap..[Order Details]FROM EPlanHeap..[Order Details]WHERE WHERE OrderID <OrderID < 10250 10250

AND Productid < 50 AND Productid < 50

Page 67: select top 10 * from orders

67

Auto-ParameterizationAuto-Parameterization

Pure Ad Hoc Pure Ad Hoc 쿼리에 대한 자동화된 쿼리에 대한 자동화된 Caching Caching 전략 중의 하나전략 중의 하나 Ad Hoc cachingAd Hoc caching Auto parameterizationAuto parameterization

동일한 쿼리 구조동일한 쿼리 구조 , Parameter, Parameter 만 변경되는 경우에 해당만 변경되는 경우에 해당 ParameterParameter 가 될 수 있는 가 될 수 있는 Constants Constants 결정결정 Safe ParameterSafe Parameter 에 대한 에 대한 Parameterized Template Parameterized Template 생성생성 Prepared Plan Prepared Plan 에 해당에 해당

SELECT OrderDate, OrderIDSELECT OrderDate, OrderIDFROM OrdersFROM OrdersWHERE OrderID = 10258WHERE OrderID = 10258

SELECT OrderDate, OrderIDSELECT OrderDate, OrderIDFROM OrdersFROM OrdersWHERE OrderID = 10258WHERE OrderID = 10258

master..syscacheobjectsmaster..syscacheobjects

(@1 smallint)(@1 smallint)SELECT[OrderDate]=[OrderDate],[OrderID]=[OrderID] SELECT[OrderDate]=[OrderDate],[OrderID]=[OrderID] FROM [Orders] WHERE [OrderID] = @1FROM [Orders] WHERE [OrderID] = @1

master..syscacheobjectsmaster..syscacheobjects

(@1 smallint)(@1 smallint)SELECT[OrderDate]=[OrderDate],[OrderID]=[OrderID] SELECT[OrderDate]=[OrderDate],[OrderID]=[OrderID] FROM [Orders] WHERE [OrderID] = @1FROM [Orders] WHERE [OrderID] = @1

Page 68: select top 10 * from orders

68

- INDEX (OrderID - INDEX (OrderID ASCASC))- INDEX (OrderID - INDEX (OrderID ASCASC))

BETWEEN BETWEEN

Col1 Col1 BETWEENBETWEEN @1 @1 ANDAND @2 @2

동일동일Col1 Col1 >=>= @1 AND Col1 @1 AND Col1 <=<= @2 @2

저장된 인덱스 키의 정렬 순서저장된 인덱스 키의 정렬 순서 (DESC, ASC)(DESC, ASC) 에 따라 에 따라 조건식 변형조건식 변형

datetime/smalldatetime datetime/smalldatetime 데이터 형 처리 시 주의데이터 형 처리 시 주의

SELECT *SELECT *FROM OrdersFROM OrdersWHERE OrderID BETWEEN 10248 AND 10250WHERE OrderID BETWEEN 10248 AND 10250

SELECT *SELECT *FROM OrdersFROM OrdersWHERE OrderID BETWEEN 10248 AND 10250WHERE OrderID BETWEEN 10248 AND 10250

- INDEX (OrderID - INDEX (OrderID DESCDESC))- INDEX (OrderID - INDEX (OrderID DESCDESC))

Page 69: select top 10 * from orders

69

LIKELIKE

검색 처리 과정검색 처리 과정 인덱스 사용하는 경우인덱스 사용하는 경우

SEEK: (SEEK: ( 검색 범위 제한검색 범위 제한 ) ) WHERE: (like (WHERE: (like (패턴 매칭패턴 매칭 ) )) )

인덱스 사용 않는 경우인덱스 사용 않는 경우 WHERE: (like (WHERE: (like (패턴 매칭패턴 매칭 ) )) )

주의주의 . . Non-SARGNon-SARG 조건식을 패턴 문자로 시작조건식을 패턴 문자로 시작

ex. LIKE ‘%ANAT%’ex. LIKE ‘%ANAT%’ 예외 패턴예외 패턴

ex. LIKE ‘[^QR]%’ex. LIKE ‘[^QR]%’

Page 70: select top 10 * from orders

70

Index (CustomerID)Index (CustomerID)Index (CustomerID)Index (CustomerID)

LIKE LIKE 사례사례

SELECT * FROM OrdersSELECT * FROM OrdersWHERE CustomerID LIKE ‘ANAT%'WHERE CustomerID LIKE ‘ANAT%'

SELECT * FROM OrdersSELECT * FROM OrdersWHERE CustomerID LIKE ‘ANAT%'WHERE CustomerID LIKE ‘ANAT%'

SELECT * FROM Orders SELECT * FROM Orders WHERE CustomerID LIKE ‘ANAT_'WHERE CustomerID LIKE ‘ANAT_'

SELECT * FROM Orders SELECT * FROM Orders WHERE CustomerID LIKE ‘ANAT_'WHERE CustomerID LIKE ‘ANAT_'

SELECT * FROM OrdersSELECT * FROM OrdersWHERE CustomerID LIKE 'WHERE CustomerID LIKE '%%ANAT%'ANAT%'

SELECT * FROM OrdersSELECT * FROM OrdersWHERE CustomerID LIKE 'WHERE CustomerID LIKE '%%ANAT%'ANAT%'

SELECT * FROM Orders SELECT * FROM Orders WHERE CustomerID LIKE '[WHERE CustomerID LIKE '[^̂QR]%'QR]%'

SELECT * FROM Orders SELECT * FROM Orders WHERE CustomerID LIKE '[WHERE CustomerID LIKE '[^̂QR]%'QR]%'

Page 71: select top 10 * from orders

71

Index (Quantity)Index (Quantity)Index (Quantity)Index (Quantity)

EXISTS vs. COUNT(*)EXISTS vs. COUNT(*)

IF IF EXISTS (EXISTS (SELECT * SELECT * FROM Eplan..[Order Details] FROM Eplan..[Order Details] WHERE Quantity > 50WHERE Quantity > 50))

IF IF EXISTS (EXISTS (SELECT * SELECT * FROM Eplan..[Order Details] FROM Eplan..[Order Details] WHERE Quantity > 50WHERE Quantity > 50))

IF (SELECT IF (SELECT COUNT(*)COUNT(*) FROM Eplan..[Order Details] FROM Eplan..[Order Details] WHERE Quantity > 50) WHERE Quantity > 50) > 0> 0

IF (SELECT IF (SELECT COUNT(*)COUNT(*) FROM Eplan..[Order Details] FROM Eplan..[Order Details] WHERE Quantity > 50) WHERE Quantity > 50) > 0> 0

Page 72: select top 10 * from orders

72

NOTNOT

주의해야 할 연산자주의해야 할 연산자 Non-SARGNon-SARG 에서 다룸에서 다룸

Page 73: select top 10 * from orders

73

AND vs. OR AND vs. OR 연산자연산자

동일 쿼리에서 같은 테이블의 다중 인덱스를 사용하기 위한 전략동일 쿼리에서 같은 테이블의 다중 인덱스를 사용하기 위한 전략 AND (Index Interchange)AND (Index Interchange)

검색 칼럼 각각에 대한 유용성을 평가검색 칼럼 각각에 대한 유용성을 평가

WHERE WHERE A = ?A = ? ANDAND B = ?B = ?

- A - A 인덱스 효율적인 경우 사용인덱스 효율적인 경우 사용- B - B 인덱스 효율적인 경우 사용인덱스 효율적인 경우 사용- - 사용된 인덱스 검색 결과를 사용된 인덱스 검색 결과를 JOIN JOIN 으로 교집합 산출으로 교집합 산출- - 비 효율적인 조건은 비 효율적인 조건은 Filter Filter 같은 부가 연산자 적용같은 부가 연산자 적용

OR OR 와 와 ININ 조건 조건 (Union Index, Merge Index)(Union Index, Merge Index)검색 칼럼 모두에 대한 유용성 평가검색 칼럼 모두에 대한 유용성 평가

WHERE WHERE A = ? A = ? OROR B = ? B = ?

- A, B - A, B 인덱스 모두 효율적인 경우에만 사용인덱스 모두 효율적인 경우에만 사용- - 인덱스 검색 결과를 인덱스 검색 결과를 UNIONUNION 으로 합집합 산출 으로 합집합 산출 - - 그렇지 않으면그렇지 않으면 , Scan, Scan

Page 74: select top 10 * from orders

74

Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)

Index InterchangeIndex Interchange

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'greal' AND OrderDate = '19980430'WHERE Customerid = 'greal' AND OrderDate = '19980430'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'greal' AND OrderDate = '19980430'WHERE Customerid = 'greal' AND OrderDate = '19980430'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'QUEEN‘ AND OrderDate = '19970107'WHERE Customerid = 'QUEEN‘ AND OrderDate = '19970107'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'QUEEN‘ AND OrderDate = '19970107'WHERE Customerid = 'QUEEN‘ AND OrderDate = '19970107'

33

1111

22

Page 75: select top 10 * from orders

75

Union Index (Merge Index)Union Index (Merge Index)

Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)Index (CustomerID), Index (OrderDate)

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'BOLID‘ OR OrderDate = '19970107'WHERE Customerid = 'BOLID‘ OR OrderDate = '19970107'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'BOLID‘ OR OrderDate = '19970107'WHERE Customerid = 'BOLID‘ OR OrderDate = '19970107'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'QUEEN‘ OR OrderDate = '19970107'WHERE Customerid = 'QUEEN‘ OR OrderDate = '19970107'

SELECT * FROM dbo.OrdersSELECT * FROM dbo.OrdersWHERE Customerid = 'QUEEN‘ OR OrderDate = '19970107'WHERE Customerid = 'QUEEN‘ OR OrderDate = '19970107'

33

22

1144

Page 76: select top 10 * from orders

76

IN IN 사례사례

Index (PK, OrderID)Index (PK, OrderID)Index (PK, OrderID)Index (PK, OrderID)

SELECT * FROM EPlanHeap..Orders SELECT * FROM EPlanHeap..Orders WHERE OrderID IN ( 10248, 10249, 10250, WHERE OrderID IN ( 10248, 10249, 10250,

10251, 10252, 10253, 10251, 10252, 10253, 10254, 10255, 10256 )10254, 10255, 10256 )

SELECT * FROM EPlanHeap..Orders SELECT * FROM EPlanHeap..Orders WHERE OrderID IN ( 10248, 10249, 10250, WHERE OrderID IN ( 10248, 10249, 10250,

10251, 10252, 10253, 10251, 10252, 10253, 10254, 10255, 10256 )10254, 10255, 10256 )

SELECT * FROM EPlanHeap..Orders SELECT * FROM EPlanHeap..Orders WHERE OrderID IN ( 10248, 10249, 10250, WHERE OrderID IN ( 10248, 10249, 10250,

10251, 10252, 10253, 10251, 10252, 10253, 10254, 10255, 10256, 10254, 10255, 10256, 1025710257 ) )

SELECT * FROM EPlanHeap..Orders SELECT * FROM EPlanHeap..Orders WHERE OrderID IN ( 10248, 10249, 10250, WHERE OrderID IN ( 10248, 10249, 10250,

10251, 10252, 10253, 10251, 10252, 10253, 10254, 10255, 10256, 10254, 10255, 10256, 1025710257 ) )

Page 77: select top 10 * from orders

77

ORDER BYORDER BY

SortSort 성능상 이슈성능상 이슈

길이 별길이 별 , , 칼럼 개수 별칼럼 개수 별 , , 데이터 타입 별데이터 타입 별 관련 연산자관련 연산자

GROUP BY / DISTINCTGROUP BY / DISTINCT TOPTOP MERGEMERGE

Sort Sort 와 와 IndexIndex Index Index 생성 시 중간 작업생성 시 중간 작업 Leaf Level (or Data Page) Leaf Level (or Data Page) 역할역할 ORDERED {Forward | Backward}ORDERED {Forward | Backward} Composite IndexComposite Index

WHERE WHERE 절과 절과 ORDER BY ORDER BY 절 처리절 처리 두 번째 칼럼부터 정렬 순서 문제두 번째 칼럼부터 정렬 순서 문제

Page 78: select top 10 * from orders

78

집계함수와 집계함수와 GROUP BYGROUP BY

집계 함수집계 함수 COUNT(*) vs. COUNT(expression)COUNT(*) vs. COUNT(expression) GROUP BY GROUP BY ROLLUP and CUBEROLLUP and CUBE

Page 79: select top 10 * from orders

79

집계 함수집계 함수 (( 함수 별 차이함수 별 차이 ))

MIN(), MAX() MIN(), MAX() 함수와 다른 함수의 차이함수와 다른 함수의 차이

SELECT MIN(IndexKey), MAX(IndexKey) SELECT MIN(IndexKey), MAX(IndexKey) vs.vs. UNION UNION 공통 연산자 공통 연산자 TOPTOP Join vs. ConcatenationJoin vs. Concatenation 비용비용 , Compile Time, Auto Caching, Compile Time, Auto Caching 의 차이의 차이

Heap Heap 기반기반Heap Heap 기반기반

SELECT COUNT(*), AVG(UnitPrice)SELECT COUNT(*), AVG(UnitPrice)FROM dbo.[Order Details]FROM dbo.[Order Details]

SELECT COUNT(*), AVG(UnitPrice)SELECT COUNT(*), AVG(UnitPrice)FROM dbo.[Order Details]FROM dbo.[Order Details]

SELECT MIN(Quantity), MAX(Quantity)SELECT MIN(Quantity), MAX(Quantity)FROM dbo.[Order Details]FROM dbo.[Order Details]

SELECT MIN(Quantity), MAX(Quantity)SELECT MIN(Quantity), MAX(Quantity)FROM dbo.[Order Details]FROM dbo.[Order Details]

Page 80: select top 10 * from orders

80

COUNT(*) vs. COUNT(expression)COUNT(*) vs. COUNT(expression)

COUNT(*) COUNT(*) vs. COUNT( [ALL | DISTINCT] vs. COUNT( [ALL | DISTINCT] expressionexpression ) ) vs. with NULLvs. with NULL

Page 81: select top 10 * from orders

81

GROUP BYGROUP BY

AggregateAggregate 성능 이슈성능 이슈

인덱스 사용 여부인덱스 사용 여부 , , 행 그룹 수행 그룹 수 기타기타 , , 기본적인 데이터 성능 고려 기본적인 데이터 성능 고려 (ORDER BY (ORDER BY 참조참조 ))

관련 연산자관련 연산자 Stream AggregateStream Aggregate

비교적 작은 집합이나 미리 정렬된 집합에 사용 권장비교적 작은 집합이나 미리 정렬된 집합에 사용 권장 정렬된 입력정렬된 입력 , , 정렬된 출력정렬된 출력

Hash MatchHash Match 큰 집합에 사용 권장큰 집합에 사용 권장 해시를 작성하면서 집계 계산해시를 작성하면서 집계 계산 , , 높은 높은 CPU CPU 사용률사용률 입력입력 // 출력은 임의 순서출력은 임의 순서

SortSort HAVINGHAVING

Filter Filter 연산자 사용연산자 사용 실행 계획은 실행 계획은 DemoDemo 로 참조 로 참조 (DISTINCT (DISTINCT 에서 다른 예제도 언급됨에서 다른 예제도 언급됨 ))

Page 82: select top 10 * from orders

82

ROLLUP and CUBEROLLUP and CUBE

SELECT orderid, productid, SUM(quantity) AS total_quantitySELECT orderid, productid, SUM(quantity) AS total_quantityFROM [order details]FROM [order details]WHERE orderid < 10250 WHERE orderid < 10250 GROUP BY orderid, productid GROUP BY orderid, productid WITH ROLLUPWITH ROLLUP

SELECT orderid, productid, SUM(quantity) AS total_quantitySELECT orderid, productid, SUM(quantity) AS total_quantityFROM [order details]FROM [order details]WHERE orderid < 10250 WHERE orderid < 10250 GROUP BY orderid, productid GROUP BY orderid, productid WITH ROLLUPWITH ROLLUP

SELECT orderid, productid, SUM(quantity) AS total_quantitySELECT orderid, productid, SUM(quantity) AS total_quantityFROM [order details]FROM [order details]WHERE orderid < 10250WHERE orderid < 10250GROUP BY orderid, productid GROUP BY orderid, productid WITH CUBEWITH CUBE

SELECT orderid, productid, SUM(quantity) AS total_quantitySELECT orderid, productid, SUM(quantity) AS total_quantityFROM [order details]FROM [order details]WHERE orderid < 10250WHERE orderid < 10250GROUP BY orderid, productid GROUP BY orderid, productid WITH CUBEWITH CUBE

Page 83: select top 10 * from orders

83

JOINJOIN

NESTED LOOP JOINNESTED LOOP JOIN HASH JOINHASH JOIN MERGE JOINMERGE JOIN SEMI JOIN and ANTI SEMI JOINSEMI JOIN and ANTI SEMI JOIN T-SQL JOIN vs. ANSI OUTER JOINT-SQL JOIN vs. ANSI OUTER JOIN UNION vs. UNION ALLUNION vs. UNION ALL

Page 84: select top 10 * from orders

84

NESTED LOOP JOINNESTED LOOP JOIN

도구 설명도구 설명 최상위최상위 (( 외부외부 ) ) 입력의 각 행에 대해 입력의 각 행에 대해 최하위최하위 (( 내부내부 ) ) 입력을 스캔하고 일치하는 행을 입력을 스캔하고 일치하는 행을

출력출력 인수인수

조건자조건자 , OUTER REFERENCES() , OUTER REFERENCES() 절절 비용 소비자비용 소비자

I/O I/O 집중적집중적 외부 입력외부 입력

= = 외부 입력 스캔 외부 입력 스캔 I/OI/O 내부 입력 내부 입력

= = 내부 입력 스캔 내부 입력 스캔 I/O x I/O x 스캔 수스캔 수 (( 실행 실행 횟수횟수 ))

CPUCPU 행 개수행 개수

Page 85: select top 10 * from orders

85

NESTED LOOP JOIN NESTED LOOP JOIN 사례 사례 - 1- 1

부모가 내부 입력이 되는 경우 부모가 내부 입력이 되는 경우 (*(* 조건조건 : : 테이블은 항상 고유 식별자를 가진다테이블은 항상 고유 식별자를 가진다 ))

자식이 내부 입력이 되는 경우자식이 내부 입력이 되는 경우 FKFK 가 가 PKPK 의 일부인 경우 의 일부인 경우 - PK- PK 의 선두 칼럼의 선두 칼럼 (( 들들 )) 이 상속된 칼럼인 이 상속된 칼럼인

경우경우

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

SELECT *SELECT *FROM Northwind..Customers ct FROM Northwind..Customers ct INNER JOIN Northwind..Orders omINNER JOIN Northwind..Orders om ON ct.CustomerID = om.CustomerIDON ct.CustomerID = om.CustomerIDWHERE om.OrderID < 10250WHERE om.OrderID < 10250

SELECT *SELECT *FROM Northwind..Customers ct FROM Northwind..Customers ct INNER JOIN Northwind..Orders omINNER JOIN Northwind..Orders om ON ct.CustomerID = om.CustomerIDON ct.CustomerID = om.CustomerIDWHERE om.OrderID < 10250WHERE om.OrderID < 10250

22

Orders(PK) Orders(PK) [Order Details](FK) [Order Details](FK)Orders(PK) Orders(PK) [Order Details](FK) [Order Details](FK)

SELECT *SELECT *FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON o.OrderID = od.OrderIDON o.OrderID = od.OrderIDWHERE o.OrderID = 10248WHERE o.OrderID = 10248

SELECT *SELECT *FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON o.OrderID = od.OrderIDON o.OrderID = od.OrderIDWHERE o.OrderID = 10248WHERE o.OrderID = 10248

Page 86: select top 10 * from orders

86

NESTED LOOP JOIN NESTED LOOP JOIN 사례 사례 - 2- 2

자식이 내부 입력이 되는 경우자식이 내부 입력이 되는 경우 FKFK 가 가 PKPK 의 일부의 일부 (Partial(Partial 키키 ) ) 인 경우 인 경우 - PK- PK 의 선두 칼럼이 아닌 경우의 선두 칼럼이 아닌 경우

FKFK 가 일반 칼럼인 경우 가 일반 칼럼인 경우 - INDEX- INDEX 가 있는 경우가 있는 경우

Products(PK) Products(PK) [Order Details](FK) [Order Details](FK)Products(PK) Products(PK) [Order Details](FK) [Order Details](FK)

SELECT *SELECT *FROM Northwind..Products p FROM Northwind..Products p INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON p.ProductID = od.ProductIDON p.ProductID = od.ProductIDWHERE p.ProductID = 1WHERE p.ProductID = 1

SELECT *SELECT *FROM Northwind..Products p FROM Northwind..Products p INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON p.ProductID = od.ProductIDON p.ProductID = od.ProductIDWHERE p.ProductID = 1WHERE p.ProductID = 1

Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)

SELECT *SELECT *FROM Northwind..Products o FROM Northwind..Products o INNER JOIN Northwind..Suppliers odINNER JOIN Northwind..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid = 2WHERE od.Supplierid = 2

SELECT *SELECT *FROM Northwind..Products o FROM Northwind..Products o INNER JOIN Northwind..Suppliers odINNER JOIN Northwind..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid = 2WHERE od.Supplierid = 2

Page 87: select top 10 * from orders

87

NESTED LOOP JOIN NESTED LOOP JOIN 사례 사례 - 3- 3

FKFK 가 일반 칼럼인 경우 가 일반 칼럼인 경우 - INDEX- INDEX 가 없는 경우가 없는 경우

자식에 대한 스캔 수가 많은 경우 자식에 대한 스캔 수가 많은 경우 (( 자식이 외부 입력으로 전환자식이 외부 입력으로 전환 ))

SORT LOOP JOIN (SORT LOOP JOIN (DemoDemo 로 참조로 참조 ))

Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)

SELECT *SELECT *FROM EPlan..Products o FROM EPlan..Products o INNER JOIN EPlan..Suppliers odINNER JOIN EPlan..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid = 2WHERE od.Supplierid = 2

SELECT *SELECT *FROM EPlan..Products o FROM EPlan..Products o INNER JOIN EPlan..Suppliers odINNER JOIN EPlan..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid = 2WHERE od.Supplierid = 2

Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)Suppliers(PK) Suppliers(PK) Products(FK) Products(FK)

SELECT *SELECT *FROM EPlan..Products o FROM EPlan..Products o INNER JOIN EPlan..Suppliers odINNER JOIN EPlan..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid <= 2WHERE od.Supplierid <= 2

SELECT *SELECT *FROM EPlan..Products o FROM EPlan..Products o INNER JOIN EPlan..Suppliers odINNER JOIN EPlan..Suppliers od ON o.Supplierid = od.SupplieridON o.Supplierid = od.SupplieridWHERE od.Supplierid <= 2WHERE od.Supplierid <= 2

11

77

Page 88: select top 10 * from orders

88

HASH JOIN HASH JOIN

도구 설명도구 설명 최상위최상위 입력의 각 행을 사용입력의 각 행을 사용 , , 해시 테이블 해시 테이블

작성 작성 (Build Input, (Build Input, 빌드 입력빌드 입력 )) 최하위 입력에서 각 행을 사용최하위 입력에서 각 행을 사용 , , 해시 해시

테이블을 검색테이블을 검색 , , 일치하는 모든 행 출력 일치하는 모든 행 출력 (Probe Input, (Probe Input, 검색 입력검색 입력 ))

인수인수 해시 열해시 열 (( 해시 키해시 키 ) ) 목록목록 , HASH:() , HASH:() 절절 잔여 조건자잔여 조건자 , RESIDUAL:(), RESIDUAL:()

비용 소비자비용 소비자 I/OI/O

외부 입력 외부 입력 = = 외부 입력 스캔 외부 입력 스캔 IOIO 내부 입력 내부 입력 = = 내부 입력 스캔 내부 입력 스캔 IOIO

CPU CPU 집중적집중적 해시 함수해시 함수 , , 해시 키 계산해시 키 계산 , , 해시 버킷 해시 버킷

스캔스캔 행 개수행 개수

Page 89: select top 10 * from orders

89

HASH JOIN HASH JOIN 사례사례

작은 작은 Build InputBuild Input

““ 역할 반전역할 반전””

Employees(PK) Employees(PK) Orders(FK) Orders(FK)Employees(PK) Employees(PK) Orders(FK) Orders(FK)

SELECT *SELECT *FROM EPlan..Orders o FROM EPlan..Orders o INNER JOIN EPlan..Employees eINNER JOIN EPlan..Employees e ON o.EmployeeID = e.EmployeeIDON o.EmployeeID = e.EmployeeID

SELECT *SELECT *FROM EPlan..Orders o FROM EPlan..Orders o INNER JOIN EPlan..Employees eINNER JOIN EPlan..Employees e ON o.EmployeeID = e.EmployeeIDON o.EmployeeID = e.EmployeeID

Employees(PK) Employees(PK) Orders(FK) Orders(FK)Employees(PK) Employees(PK) Orders(FK) Orders(FK)

SELECT *SELECT *FROM EPlan..Orders o FROM EPlan..Orders o INNER JOIN EPlan..Employees eINNER JOIN EPlan..Employees e ON o.EmployeeID = e.EmployeeIDON o.EmployeeID = e.EmployeeIDOPTION (HASH JOIN, FORCE ORDER)OPTION (HASH JOIN, FORCE ORDER)

SELECT *SELECT *FROM EPlan..Orders o FROM EPlan..Orders o INNER JOIN EPlan..Employees eINNER JOIN EPlan..Employees e ON o.EmployeeID = e.EmployeeIDON o.EmployeeID = e.EmployeeIDOPTION (HASH JOIN, FORCE ORDER)OPTION (HASH JOIN, FORCE ORDER)

CPU CPU 비용비용 : 0.0274: 0.0274

CPU CPU 비용비용 : 0.146: 0.146

Page 90: select top 10 * from orders

90

MERGE JOINMERGE JOIN

도구 설명도구 설명 적절하게 정렬된 두 입력 테이블에서 정렬 적절하게 정렬된 두 입력 테이블에서 정렬

순서를 이용하여 행을 대응순서를 이용하여 행을 대응 인수인수

1:M 1:M 조인조인 , MERGE:() , MERGE:() 절절 M:M M:M 조인조인 , MANY-TO-MANY MERGE:(), MANY-TO-MANY MERGE:() 잔여 조건자잔여 조건자 , RESIDUAL:(), RESIDUAL:()

비용 소비자비용 소비자 I/O I/O

외부 입력 외부 입력 = = 외부 입력 스캔 외부 입력 스캔 IOIO 내부 입력 내부 입력 = = 내부 입력 스캔 내부 입력 스캔 IOIO

CPUCPU 행 개수행 개수

추가 비용 발생 추가 비용 발생 (I/O, CPU (I/O, CPU 집중적집중적 )) Sort Merge JOINSort Merge JOIN M:M M:M 조인 시 조인 시 worktable worktable 발생발생

Page 91: select top 10 * from orders

91

MERGE JOIN MERGE JOIN 사례사례

1:M 1:M 조인조인

M:M M:M 조인조인

Sort Merge Sort Merge 조인 조인 ((DemoDemo 로 참조로 참조 ))

Orders(PK) Orders(PK) [Order Details] (FK) [Order Details] (FK)Orders(PK) Orders(PK) [Order Details] (FK) [Order Details] (FK)

SELECT *SELECT *FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON o.OrderID = od.OrderIDON o.OrderID = od.OrderID

SELECT *SELECT *FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..[Order Details] odINNER JOIN Northwind..[Order Details] od ON o.OrderID = od.OrderIDON o.OrderID = od.OrderID

Orders(PK) Orders(PK) [Order Details] (FK) [Order Details] (FK)Orders(PK) Orders(PK) [Order Details] (FK) [Order Details] (FK)

SELECT *SELECT *FROM Northwind..[Order Details] od FROM Northwind..[Order Details] od INNER MERGE JOIN Northwind..Orders o INNER MERGE JOIN Northwind..Orders o ON o.OrderID = od.OrderIDON o.OrderID = od.OrderID

SELECT *SELECT *FROM Northwind..[Order Details] od FROM Northwind..[Order Details] od INNER MERGE JOIN Northwind..Orders o INNER MERGE JOIN Northwind..Orders o ON o.OrderID = od.OrderIDON o.OrderID = od.OrderID

Page 92: select top 10 * from orders

92

SEMI JOIN and ANTI SEMI JOINSEMI JOIN and ANTI SEMI JOIN

{LEFT | RIGHT} SEMI JOIN{LEFT | RIGHT} SEMI JOIN

{LEFT | RIGHT} ANTI SEMI JOIN{LEFT | RIGHT} ANTI SEMI JOIN

Products(PK) Products(PK) [Order Details] (FK) [Order Details] (FK)Products(PK) Products(PK) [Order Details] (FK) [Order Details] (FK)

SELECT pr.* SELECT pr.* FROM Northwind..Products prFROM Northwind..Products prWHERE EXISTS WHERE EXISTS ( SELECT * ( SELECT * FROM Northwind..[Order Details] odFROM Northwind..[Order Details] od WHERE od.Productid = pr.Productid )WHERE od.Productid = pr.Productid )

SELECT pr.* SELECT pr.* FROM Northwind..Products prFROM Northwind..Products prWHERE EXISTS WHERE EXISTS ( SELECT * ( SELECT * FROM Northwind..[Order Details] odFROM Northwind..[Order Details] od WHERE od.Productid = pr.Productid )WHERE od.Productid = pr.Productid )

titles(PK) titles(PK) sales (FK) sales (FK)titles(PK) titles(PK) sales (FK) sales (FK)

SELECT ti.* SELECT ti.* FROM pubs.dbo.titles tiFROM pubs.dbo.titles tiWHERE title_id WHERE title_id NOT IN (SELECT title_id NOT IN (SELECT title_id

FROM pubs.dbo.sales sa)FROM pubs.dbo.sales sa)

SELECT ti.* SELECT ti.* FROM pubs.dbo.titles tiFROM pubs.dbo.titles tiWHERE title_id WHERE title_id NOT IN (SELECT title_id NOT IN (SELECT title_id

FROM pubs.dbo.sales sa)FROM pubs.dbo.sales sa)

??

Page 93: select top 10 * from orders

93

T-SQL vs. ANSI OUTER JOINT-SQL vs. ANSI OUTER JOIN

T-SQL T-SQL 외부 조인외부 조인

ANSI SQL-92 ANSI SQL-92 외부 조인외부 조인

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

SELECT *SELECT *FROM Northwind..Customers AS c , FROM Northwind..Customers AS c , Northwind..Orders AS oNorthwind..Orders AS oWHERE c.Customerid *= o.CustomeridWHERE c.Customerid *= o.Customerid AND o.OrderDate < '19960706'AND o.OrderDate < '19960706'

SELECT *SELECT *FROM Northwind..Customers AS c , FROM Northwind..Customers AS c , Northwind..Orders AS oNorthwind..Orders AS oWHERE c.Customerid *= o.CustomeridWHERE c.Customerid *= o.Customerid AND o.OrderDate < '19960706'AND o.OrderDate < '19960706'

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

SELECT *SELECT *FROM Northwind..Customers AS c FROM Northwind..Customers AS c LEFT JOIN Northwind..Orders AS oLEFT JOIN Northwind..Orders AS o ON c.Customerid = o.CustomeridON c.Customerid = o.CustomeridWHEREWHERE o.OrderDate < '19960706'o.OrderDate < '19960706'

SELECT *SELECT *FROM Northwind..Customers AS c FROM Northwind..Customers AS c LEFT JOIN Northwind..Orders AS oLEFT JOIN Northwind..Orders AS o ON c.Customerid = o.CustomeridON c.Customerid = o.CustomeridWHEREWHERE o.OrderDate < '19960706'o.OrderDate < '19960706'

Page 94: select top 10 * from orders

94

UNION UNION

ConcatenationConcatenation 도구 설명도구 설명

출력 테이블을 작성하기 위해 여러 입력 출력 테이블을 작성하기 위해 여러 입력 테이블을 추가테이블을 추가

성능 이슈성능 이슈 행 집합 크기행 집합 크기 DINTINCT DINTINCT 연산자 연산자 (UNION ALL (UNION ALL 로 제거로 제거 ))

관련 연산자관련 연산자 MergeMerge UnionUnion Hash UnionHash Union ConcatenationConcatenation

비용 소비자비용 소비자 물리적 연산자에 따른 비용 발생물리적 연산자에 따른 비용 발생

실행 계획은 실행 계획은 DemoDemo 로 참조로 참조

Page 95: select top 10 * from orders

95

UNION vs. UNION ALLUNION vs. UNION ALL

UNIONUNION

UNION ALLUNION ALL

SELECT firstname, citySELECT firstname, city FROM Northwind..EmployeesFROM Northwind..EmployeesUNIONUNIONSELECT companyname, citySELECT companyname, city FROM Northwind..CustomersFROM Northwind..Customers

SELECT firstname, citySELECT firstname, city FROM Northwind..EmployeesFROM Northwind..EmployeesUNIONUNIONSELECT companyname, citySELECT companyname, city FROM Northwind..CustomersFROM Northwind..Customers

SELECT firstname, citySELECT firstname, city FROM Northwind..EmployeesFROM Northwind..EmployeesUNION ALLUNION ALLSELECT companyname, citySELECT companyname, city FROM Northwind..CustomersFROM Northwind..Customers

SELECT firstname, citySELECT firstname, city FROM Northwind..EmployeesFROM Northwind..EmployeesUNION ALLUNION ALLSELECT companyname, citySELECT companyname, city FROM Northwind..CustomersFROM Northwind..Customers

Page 96: select top 10 * from orders

96

Subquery Subquery 사례사례

사례사례 : : 파생 테이블파생 테이블 (Derived Table)(Derived Table) Subquery Subquery 처리 방법처리 방법 사례사례 : Subqueries for Paging: Subqueries for Paging

Page 97: select top 10 * from orders

97

사례사례 : : 파생 테이블파생 테이블 (Derived Table) – (Derived Table) – 1/21/2 집합 연산 순서의 조정집합 연산 순서의 조정

일반 조인의 경우일반 조인의 경우

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

SELECT c.Companyname, c.Phone, COUNT(*)SELECT c.Companyname, c.Phone, COUNT(*)FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..Customers cINNER JOIN Northwind..Customers c ON o.Customerid = c.CustomeridON o.Customerid = c.CustomeridGROUP BY c.Companyname, c.phoneGROUP BY c.Companyname, c.phone

SELECT c.Companyname, c.Phone, COUNT(*)SELECT c.Companyname, c.Phone, COUNT(*)FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN Northwind..Customers cINNER JOIN Northwind..Customers c ON o.Customerid = c.CustomeridON o.Customerid = c.CustomeridGROUP BY c.Companyname, c.phoneGROUP BY c.Companyname, c.phone

11

NN

1:N1:N

11 NN

Page 98: select top 10 * from orders

98

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

사례사례 : : 파생 테이블 파생 테이블 - 2/2- 2/2

집합 연산 순서의 조정집합 연산 순서의 조정 파생 테이블 활용한 경우파생 테이블 활용한 경우

SELECT c.Companyname, c.Phone, o.totalSELECT c.Companyname, c.Phone, o.totalFROM FROM ( SELECT Customerid, COUNT(*) total( SELECT Customerid, COUNT(*) total

FROM Northwind..Orders FROM Northwind..Orders GROUP BY Customerid )GROUP BY Customerid ) o o

INNER JOIN Northwind..Customers cINNER JOIN Northwind..Customers c ON o.Customerid = c.CustomeridON o.Customerid = c.Customerid

SELECT c.Companyname, c.Phone, o.totalSELECT c.Companyname, c.Phone, o.totalFROM FROM ( SELECT Customerid, COUNT(*) total( SELECT Customerid, COUNT(*) total

FROM Northwind..Orders FROM Northwind..Orders GROUP BY Customerid )GROUP BY Customerid ) o o

INNER JOIN Northwind..Customers cINNER JOIN Northwind..Customers c ON o.Customerid = c.CustomeridON o.Customerid = c.Customerid

11

NN

1:11:1

1111

Page 99: select top 10 * from orders

99

Subquery Subquery 처리 방법처리 방법

JOIN ( JOIN ( flattened flattened ) – ) – 논외로 한다논외로 한다 연산 방법이 항상 동일한 것이 아니다연산 방법이 항상 동일한 것이 아니다

Out-To-InOut-To-In

In-To-OutIn-To-Out

Customers(PK) Customers(PK) Orders(FK) Orders(FK)Customers(PK) Customers(PK) Orders(FK) Orders(FK)

SELECT c.*SELECT c.*FROM Northwind..Customers AS cFROM Northwind..Customers AS cWHERE Exists ( WHERE Exists ( SELECT *SELECT * FROM Northwind..Orders AS oFROM Northwind..Orders AS o WHERE o.CustomerID = c.CustomerID )WHERE o.CustomerID = c.CustomerID )AND c.CustomerID LIKE 'Q%'AND c.CustomerID LIKE 'Q%'

SELECT c.*SELECT c.*FROM Northwind..Customers AS cFROM Northwind..Customers AS cWHERE Exists ( WHERE Exists ( SELECT *SELECT * FROM Northwind..Orders AS oFROM Northwind..Orders AS o WHERE o.CustomerID = c.CustomerID )WHERE o.CustomerID = c.CustomerID )AND c.CustomerID LIKE 'Q%'AND c.CustomerID LIKE 'Q%'

Orders(PK) Orders(PK) [Order Details](FK) [Order Details](FK)Orders(PK) Orders(PK) [Order Details](FK) [Order Details](FK)

SELECT OrderID, CustomerIDSELECT OrderID, CustomerIDFROM Northwind..Orders AS oFROM Northwind..Orders AS oWHERE 20 < ( SELECT quantityWHERE 20 < ( SELECT quantity FROM Northwind..[Order Details] AS odFROM Northwind..[Order Details] AS od WHERE o.OrderID = od.OrderIDWHERE o.OrderID = od.OrderID AND od.ProductID = 23 )AND od.ProductID = 23 )

SELECT OrderID, CustomerIDSELECT OrderID, CustomerIDFROM Northwind..Orders AS oFROM Northwind..Orders AS oWHERE 20 < ( SELECT quantityWHERE 20 < ( SELECT quantity FROM Northwind..[Order Details] AS odFROM Northwind..[Order Details] AS od WHERE o.OrderID = od.OrderIDWHERE o.OrderID = od.OrderID AND od.ProductID = 23 )AND od.ProductID = 23 )

Page 100: select top 10 * from orders

100

사례사례 : Subqueries for Paging: Subqueries for Paging

1111 ~ 20~ 20번째 주문 정보 가져오기번째 주문 정보 가져오기 20042004년 초까지 가장 많았던 질문 중의 하나년 초까지 가장 많았던 질문 중의 하나 초창기 가장 많이 사용된 초창기 가장 많이 사용된 Paging Paging 쿼리쿼리 최적화가 아닌 실행 계획 비교가 목적최적화가 아닌 실행 계획 비교가 목적

1.1. Top n & NOT IN Top n & NOT IN (( 질문의 질문의 95%)95%)

2.2. vs. Top n & JOIN vs. Top n & JOIN (2.5%)(2.5%)

3.3. vs. vs. 비교 연산자 비교 연산자 & MAX() & MAX() (2.5%)(2.5%)

4.4. vs. vs. 비교 연산자 비교 연산자 & all& all

Page 101: select top 10 * from orders

101

Demo Demo 코드코드 : Subqueries for Paging: Subqueries for Paging

-- 1. Top n & NOT IN-- 1. Top n & NOT INSELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid NOT IN (SELECT TOP 10 Orderid WHERE Orderid NOT IN (SELECT TOP 10 Orderid

FROM Northwind..OrdersFROM Northwind..Orders ORDER BY Orderid ASC)ORDER BY Orderid ASC)

-- 2. Top n & JOIN-- 2. Top n & JOINSELECT * SELECT * FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN (SELECT TOP 10 Orderid INNER JOIN (SELECT TOP 10 Orderid FROM (SELECT TOP 20 Orderid FROM (SELECT TOP 20 Orderid

FROM Northwind..OrdersFROM Northwind..OrdersORDER BY Orderid ASC) dvORDER BY Orderid ASC) dv

ORDER BY Orderid DESC) dvORDER BY Orderid DESC) dvON o.Orderid = dv.OrderidON o.Orderid = dv.Orderid

ORDER BY o.OrderID ASCORDER BY o.OrderID ASC-- 3. -- 3. 비교 연산자 비교 연산자 & MAX()& MAX()SELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid > (SELECT MAX(ORDERID) WHERE Orderid > (SELECT MAX(ORDERID)

FROM (SELECT TOP 10 Orderid FROM (SELECT TOP 10 Orderid FROM Northwind..Orders FROM Northwind..Orders ORDER BY Orderid ASC) DV) ORDER BY Orderid ASC) DV)

-- 4. -- 4. 비교 연산자 비교 연산자 & all& allSELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid > all (SELECT TOP 10 Orderid WHERE Orderid > all (SELECT TOP 10 Orderid

FROM Northwind..Orders FROM Northwind..Orders ORDER BY Orderid ASC) ORDER BY Orderid ASC)

-- 1. Top n & NOT IN-- 1. Top n & NOT INSELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid NOT IN (SELECT TOP 10 Orderid WHERE Orderid NOT IN (SELECT TOP 10 Orderid

FROM Northwind..OrdersFROM Northwind..Orders ORDER BY Orderid ASC)ORDER BY Orderid ASC)

-- 2. Top n & JOIN-- 2. Top n & JOINSELECT * SELECT * FROM Northwind..Orders o FROM Northwind..Orders o INNER JOIN (SELECT TOP 10 Orderid INNER JOIN (SELECT TOP 10 Orderid FROM (SELECT TOP 20 Orderid FROM (SELECT TOP 20 Orderid

FROM Northwind..OrdersFROM Northwind..OrdersORDER BY Orderid ASC) dvORDER BY Orderid ASC) dv

ORDER BY Orderid DESC) dvORDER BY Orderid DESC) dvON o.Orderid = dv.OrderidON o.Orderid = dv.Orderid

ORDER BY o.OrderID ASCORDER BY o.OrderID ASC-- 3. -- 3. 비교 연산자 비교 연산자 & MAX()& MAX()SELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid > (SELECT MAX(ORDERID) WHERE Orderid > (SELECT MAX(ORDERID)

FROM (SELECT TOP 10 Orderid FROM (SELECT TOP 10 Orderid FROM Northwind..Orders FROM Northwind..Orders ORDER BY Orderid ASC) DV) ORDER BY Orderid ASC) DV)

-- 4. -- 4. 비교 연산자 비교 연산자 & all& allSELECT TOP 10 *SELECT TOP 10 *FROM Northwind..OrdersFROM Northwind..OrdersWHERE Orderid > all (SELECT TOP 10 Orderid WHERE Orderid > all (SELECT TOP 10 Orderid

FROM Northwind..Orders FROM Northwind..Orders ORDER BY Orderid ASC) ORDER BY Orderid ASC)

실행 계획은 실행 계획은 DemoDemo 로 확인로 확인실행 계획은 실행 계획은 DemoDemo 로 확인로 확인

Page 102: select top 10 * from orders

102

Module 3. Non-SARG Module 3. Non-SARG 사례 분석사례 분석

이발사의 집합 이야기이발사의 집합 이야기 집합집합 , , 조건 그리고 조건 그리고 SQL SQL 검색 조건검색 조건 SARGabilitySARGability Non-SARG Non-SARG 사례 분석사례 분석 추가 고려 사항추가 고려 사항 SQL Server 2005 SQL Server 2005 에서는에서는……

Page 103: select top 10 * from orders

103

이발사의 집합 이야기이발사의 집합 이야기

‘‘ 이발사의 역리이발사의 역리’’ , , 논리학자 논리학자 Bertrand RusselBertrand Russel 질문질문 , , ““ 이발사는 스스로 면도해도 되는가이발사는 스스로 면도해도 되는가 ?”?”

‘‘ 스스로 면도하지 않는 사람들을 면도해 주는 이발사스스로 면도하지 않는 사람들을 면도해 주는 이발사’’ , , 간판 문구간판 문구

‘‘ 이발사는 스스로 면도한다이발사는 스스로 면도한다 ?’?’

‘‘ 이발사는 스스로 면도하지 않는 사람들의 집합에 원소가 아니다이발사는 스스로 면도하지 않는 사람들의 집합에 원소가 아니다’’

““ 따라서따라서 , , 이발사는 스스로 면도하면 안 된다이발사는 스스로 면도하면 안 된다 !”!”

이야기의 핵심이야기의 핵심““ 집합을 묘사하기 위해 신비로운 말들을 하는 것만으로는 되지 않고집합을 묘사하기 위해 신비로운 말들을 하는 것만으로는 되지 않고 , , 원소 원소 하나 하나에 이런 신비로운 말들이 적용되는 집합을 하나 구성하는 것이 하나 하나에 이런 신비로운 말들이 적용되는 집합을 하나 구성하는 것이 관건관건”” , , 수학자 수학자 Paul R. HalmosPaul R. Halmos

Page 104: select top 10 * from orders

104

집합집합 , , 조건 그리고 조건 그리고 SQL SQL 검색 조건검색 조건

집합집합 어떤 조건에 의해 그 대상을 분명히 알 수 있는 모임어떤 조건에 의해 그 대상을 분명히 알 수 있는 모임

원소원소 집합을 이루는 대상 하나 하나집합을 이루는 대상 하나 하나

집합 조건집합 조건 집합은 원소가 무엇이냐가 아니라 어떤 성질을 갖느냐에 따라 정해진다집합은 원소가 무엇이냐가 아니라 어떤 성질을 갖느냐에 따라 정해진다 그 어떤 성질을 정하는 것이 그 어떤 성질을 정하는 것이 ‘‘조건조건’’

SQL SQL 검색 조건 검색 조건 (Search Condition), (Search Condition), 온라인 설명서 참조온라인 설명서 참조 WHERE, HAVING WHERE, HAVING 절 등에서 행 필터로서 절 등에서 행 필터로서 검색 조건검색 조건을 사용을 사용 조건을 만족시키는 행만 결과 집합조건을 만족시키는 행만 결과 집합 (Resultset)(Resultset) 을 구축을 구축 검색 조건검색 조건 (Search Condition)(Search Condition)

논리 연산자 논리 연산자 AND, OR AND, OR 및 및 NOTNOT 을 사용을 사용 , , 하나 이상의 하나 이상의 조건자조건자를 결합한 것를 결합한 것 조건자조건자 (Predicate)(Predicate)

TRUE, FALSE TRUE, FALSE 또는 또는 UNKNOWNUNKNOWN 으로 평가되는 식으로 평가되는 식

Page 105: select top 10 * from orders

105

SARGabilitySARGability

SARG (Search ARGument, SARG (Search ARGument, 검색 인수검색 인수 ) ) 소개소개 참조참조 . . “SQL Performance Tuning”“SQL Performance Tuning”, , Addison WesleyAddison Wesley

이상적인 이상적인 SQL SQL 검색 조건의 일반 형식검색 조건의 일반 형식

SARG SARG 정의정의 초기 초기 IBM researchersIBM researchers 의 정의의 정의

““SARGSARG”” Search Argument Search Argument 의 축약의 축약

““SARGableSARGable Predicates” Predicates” SARGSARG 를 만족하는 검색 조건들를 만족하는 검색 조건들

이후 이후 Microsoft Microsoft 와 와 Sybase Sybase 의 재 정의의 재 정의““SARGableSARGable, can be looked up via the index”, can be looked up via the index”

<column> <comparison operator> <literal><column> <comparison operator> <literal> <column> <comparison operator> <literal><column> <comparison operator> <literal>

Page 106: select top 10 * from orders

106

MS SQL Server, SARGMS SQL Server, SARG

SARG (SARG ( 검색 인수검색 인수 )) 검색을 제한하는 식검색을 제한하는 식

정확한 일치정확한 일치 값의 범위값의 범위 AND AND 연산자로 조인된 결합연산자로 조인된 결합

형식 형식 ((핵심핵심 : : 연산자의 한 쪽에 반드시 칼럼 혼자 나와야 한다 연산자의 한 쪽에 반드시 칼럼 혼자 나와야 한다 ))

Inclusive_OperatorInclusive_Operator =, >, <, =>, =<, BETWEEN, =, >, <, =>, =<, BETWEEN, 제한된 제한된 LIKE LIKE

SARG SARG 목적목적 ““Query OptimizerQuery Optimizer 가 쿼리 분석 단계를 간소화하고가 쿼리 분석 단계를 간소화하고 , , 최적의 실행 계획을 최적의 실행 계획을

산출하는데 기본적으로 필요한 검색 조건 식산출하는데 기본적으로 필요한 검색 조건 식”” , Microsoft, Microsoft ““OptimizerOptimizer 에게 필요한 더 많은 정보를 제공하도록 도와주는 것에게 필요한 더 많은 정보를 제공하도록 도와주는 것”” , Kalen Delaney, Kalen Delaney

Non-SARG (Non-SARG ( 비 검색 인수비 검색 인수 )) 검색을 제한하지 않는 식검색을 제한하지 않는 식

<column> <inclusive_operator> <value> [AND…]<column> <inclusive_operator> <value> [AND…] <column> <inclusive_operator> <value> [AND…]<column> <inclusive_operator> <value> [AND…]

Page 107: select top 10 * from orders

107

Non-SARG Non-SARG 사례 분석사례 분석

불필요한 칼럼 참조불필요한 칼럼 참조 불필요한 부정형 사용불필요한 부정형 사용……그러나그러나 칼럼 값 변형칼럼 값 변형

칼럼에 연산자 적용칼럼에 연산자 적용 칼럼에 함수 적용칼럼에 함수 적용 암시적 형 변환 암시적 형 변환 (( 데이터 선행 규칙 기반데이터 선행 규칙 기반 ))

부적절한 부적절한 LIKE LIKE 연산연산 기타기타 추가 고려 사항추가 고려 사항

참고참고 Clustered Index Clustered Index 기반과 기반과 Heap Heap 기반을 비교 기반을 비교 (( 필요에 따라필요에 따라 ))

Page 108: select top 10 * from orders

108

불필요한 칼럼 참조불필요한 칼럼 참조

Page 109: select top 10 * from orders

109

불필요한 부정형 사용불필요한 부정형 사용 , , 그러나그러나……

향상된 부정형 처리향상된 부정형 처리 긍정 형으로의 자동 변환긍정 형으로의 자동 변환 Clustered IndexClustered Index 의 경우에 더 나은 실행 계획의 경우에 더 나은 실행 계획

부정형은 여전히 부담스러운 작업 부정형은 여전히 부담스러운 작업 ( ( Demo Demo 참조참조 )) 긍정문으로 지향긍정문으로 지향 , , 정확한 실행 계획 평가가 중요정확한 실행 계획 평가가 중요

SELECT *SELECT *FROM EPlanHeap..ProductsFROM EPlanHeap..ProductsWHERE Discontinued <> CAST(0 as bit)WHERE Discontinued <> CAST(0 as bit)

SELECT *SELECT *FROM EPlanHeap..ProductsFROM EPlanHeap..ProductsWHERE Discontinued <> CAST(0 as bit)WHERE Discontinued <> CAST(0 as bit)

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID !> 10250WHERE OrderID !> 10250

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID !> 10250WHERE OrderID !> 10250

Page 110: select top 10 * from orders

110

칼럼 값 변형 칼럼 값 변형 1/3 – 1/3 – 칼럼에 연산자 적용칼럼에 연산자 적용

적용 결과적용 결과 Nonclustered Index Scan Nonclustered Index Scan Bookmark Lookup Bookmark Lookup

잠금 처리에 대한 성능 이득 잠금 처리에 대한 성능 이득 vs. I/O vs. I/O 비용비용 Table [ Clustered Index ] ScanTable [ Clustered Index ] Scan

Clustered Index (PK, OrderID)Clustered Index (PK, OrderID)

Index (PK, OrderID + ProductID)Index (PK, OrderID + ProductID)

Clustered Index (PK, OrderID)Clustered Index (PK, OrderID)

Index (PK, OrderID + ProductID)Index (PK, OrderID + ProductID)

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID * 1 = 10500WHERE OrderID * 1 = 10500

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID * 1 = 10500WHERE OrderID * 1 = 10500

SELECT *SELECT *FROM EPlanHeap..[Order Details] FROM EPlanHeap..[Order Details] WHERE OrderID * 1 = 10500WHERE OrderID * 1 = 10500 AND ProductID = 15AND ProductID = 15

SELECT *SELECT *FROM EPlanHeap..[Order Details] FROM EPlanHeap..[Order Details] WHERE OrderID * 1 = 10500WHERE OrderID * 1 = 10500 AND ProductID = 15AND ProductID = 15

Page 111: select top 10 * from orders

111

적용 결과 적용 결과 – – 1/3 1/3 과 동일과 동일

참고참고 Substring vs. Left [ Right ]Substring vs. Left [ Right ]

칼럼 값 변형 칼럼 값 변형 2/3 – 2/3 – 칼럼에 함수 적용칼럼에 함수 적용

Clustered Index (PK, OrderID), Index (CustomerID)Clustered Index (PK, OrderID), Index (CustomerID)

Index (OrderDate)Index (OrderDate)

Clustered Index (PK, OrderID), Index (CustomerID)Clustered Index (PK, OrderID), Index (CustomerID)

Index (OrderDate)Index (OrderDate)

SELECT OrderID, OrderDate, CustomerIDSELECT OrderID, OrderDate, CustomerIDFROM OrdersFROM OrdersWHERE Substring(CustomerID, 1, 3) = 'CEN'WHERE Substring(CustomerID, 1, 3) = 'CEN'

SELECT OrderID, OrderDate, CustomerIDSELECT OrderID, OrderDate, CustomerIDFROM OrdersFROM OrdersWHERE Substring(CustomerID, 1, 3) = 'CEN'WHERE Substring(CustomerID, 1, 3) = 'CEN'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE Convert(varchar, OrderDate, 112) = '19960704'WHERE Convert(varchar, OrderDate, 112) = '19960704'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE Convert(varchar, OrderDate, 112) = '19960704'WHERE Convert(varchar, OrderDate, 112) = '19960704'

Page 112: select top 10 * from orders

112

칼럼 값 변형 칼럼 값 변형 3/3 – 3/3 – 암시적 데이터형식 암시적 데이터형식 변환변환 처리 기준 처리 기준 – – ““ 데이터 형식 선행 규칙데이터 형식 선행 규칙” ” (Data Type Precedence)(Data Type Precedence)

데이터 형식이 다른 두 개의 식이 연산자에 의해 결합된 경우의 규칙데이터 형식이 다른 두 개의 식이 연산자에 의해 결합된 경우의 규칙 선행 규칙이 낮은 데이터 형식이 높은 데이터 형식으로 암시적 변환선행 규칙이 낮은 데이터 형식이 높은 데이터 형식으로 암시적 변환

추가 추가 Demo Demo 참조참조

Clustered Index (PK, stor_id, char[4])Clustered Index (PK, stor_id, char[4])

Clustered Index (PK, pub_id, char[4])Clustered Index (PK, pub_id, char[4])

Index (contract, bit)Index (contract, bit)

Clustered Index (PK, stor_id, char[4])Clustered Index (PK, stor_id, char[4])

Clustered Index (PK, pub_id, char[4])Clustered Index (PK, pub_id, char[4])

Index (contract, bit)Index (contract, bit)

SELECT stor_id, stor_nameSELECT stor_id, stor_nameFROM Pubs..StoresFROM Pubs..StoresWHERE stor_id = 6380WHERE stor_id = 6380

SELECT stor_id, stor_nameSELECT stor_id, stor_nameFROM Pubs..StoresFROM Pubs..StoresWHERE stor_id = 6380WHERE stor_id = 6380

SELECT pub_id, pub_name SELECT pub_id, pub_name FROM Pubs.dbo.PublishersFROM Pubs.dbo.PublishersWHERE pub_id = N'0736'WHERE pub_id = N'0736'

SELECT pub_id, pub_name SELECT pub_id, pub_name FROM Pubs.dbo.PublishersFROM Pubs.dbo.PublishersWHERE pub_id = N'0736'WHERE pub_id = N'0736'

SELECT au_id, au_lname, contract SELECT au_id, au_lname, contract FROM Pubs.dbo.AuthorsFROM Pubs.dbo.AuthorsWHERE contract = 0WHERE contract = 0

SELECT au_id, au_lname, contract SELECT au_id, au_lname, contract FROM Pubs.dbo.AuthorsFROM Pubs.dbo.AuthorsWHERE contract = 0WHERE contract = 0

Page 113: select top 10 * from orders

113

Index (CustomerID)Index (CustomerID)

Clustered Index (PK, OrderID, int)Clustered Index (PK, OrderID, int)

Index (OrderDate, datetime)Index (OrderDate, datetime)

Index (CustomerID)Index (CustomerID)

Clustered Index (PK, OrderID, int)Clustered Index (PK, OrderID, int)

Index (OrderDate, datetime)Index (OrderDate, datetime)

잘못된 잘못된 LIKE LIKE 연산연산

적용 결과적용 결과 Table [ Clustered Index ] ScanTable [ Clustered Index ] Scan

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE CustomerID LIKE '%SI%'WHERE CustomerID LIKE '%SI%'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE CustomerID LIKE '%SI%'WHERE CustomerID LIKE '%SI%'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID LIKE '1024%'WHERE OrderID LIKE '1024%'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderID LIKE '1024%'WHERE OrderID LIKE '1024%'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderDate LIKE '05% 1998%'WHERE OrderDate LIKE '05% 1998%'

SELECT OrderID, OrderDate, CustomerID SELECT OrderID, OrderDate, CustomerID FROM OrdersFROM OrdersWHERE OrderDate LIKE '05% 1998%'WHERE OrderDate LIKE '05% 1998%'

Page 114: select top 10 * from orders

114

기타기타

Non-SARGNon-SARG 로 언급되었던 나머지 식로 언급되었던 나머지 식 칼럼 간 비교칼럼 간 비교 NOT IN (), NOT EXISTS () NOT IN (), NOT EXISTS () 등등

정리 정리 – – Good SARGGood SARG 불필요한 검색 조건 식 사용을 자제불필요한 검색 조건 식 사용을 자제

Ex. Ex. COUNT(*) vs. EXISTSCOUNT(*) vs. EXISTS 명확한 검색 조건 식의 사용명확한 검색 조건 식의 사용 통계 정보에 대한 충분한 판단 정보 제공통계 정보에 대한 충분한 판단 정보 제공

실행 중이 아닌실행 중이 아닌 , , 실행 전에 칼럼에 대한 정확한 통계 정보 필요실행 전에 칼럼에 대한 정확한 통계 정보 필요 이를 위한 검색 조건 식의 변형도 고려이를 위한 검색 조건 식의 변형도 고려

OptimizerOptimizer 에 대한 충분한 이해에 대한 충분한 이해 설계 문제설계 문제 , , 버그 등에 대한 인식버그 등에 대한 인식 버전버전 (or (or 서비스 팩서비스 팩 )) 에 따른 차이점 인식에 따른 차이점 인식

Page 115: select top 10 * from orders

115

추가 고려 사항추가 고려 사항

중요한 추가 논제들중요한 추가 논제들 User Defined FunctionsUser Defined Functions

Scalar FunctionScalar Function Inline table-valued FunctionInline table-valued Function

Stored ProceduresStored Procedures Recompile Recompile 동작동작

DB DB 스키마 변경스키마 변경 통계 정보 변경 작업의 수행통계 정보 변경 작업의 수행 DDL, DML DDL, DML 혼용혼용 임시 테이블 작업임시 테이블 작업 Connection/Session Connection/Session 옵션옵션

Parameter SniffingParameter Sniffing ParameterParameter 에 따른 실행 계획의 결정에 따른 실행 계획의 결정 ParameterParameter 와 변수의 혼용와 변수의 혼용 다중 조건 처리다중 조건 처리 프로시저 내 동적 쿼리프로시저 내 동적 쿼리 etcetc

Page 116: select top 10 * from orders

116

SQL Server 2005 SQL Server 2005 에서는에서는……

Beta1~2 Beta1~2 기준기준 그래픽 실행 계획에 대한 그래픽 실행 계획에 대한 XML XML 포맷 지원포맷 지원

SET SHOWPLAN_XML ONSET SHOWPLAN_XML ON SET STATISTICS XML ONSET STATISTICS XML ON

Profiler Profiler 이벤트에서의 이벤트에서의 XML XML 포맷 지원포맷 지원 Cached Cached 쿼리에 대한 쿼리 계획 검색쿼리에 대한 쿼리 계획 검색

새로운 새로운 Dynamic Management Views (or Functions)Dynamic Management Views (or Functions) 새로운 실행 계획 연산자새로운 실행 계획 연산자 , , 기존 연산자의 변경기존 연산자의 변경

RID or Key LookupRID or Key Lookup UDX (User Defined Extensions)UDX (User Defined Extensions) Sequence [Project], etcSequence [Project], etc

향상된 쿼리 계획 출력 정보향상된 쿼리 계획 출력 정보

Page 117: select top 10 * from orders

117

감사합니다감사합니다 !!

- Q/A- Q/A- Microsoft - Microsoft 뉴스그룹뉴스그룹

서버서버 : news.microsoft.com: news.microsoft.com

뉴스그룹뉴스그룹 : microsoft.public.kr.sql: microsoft.public.kr.sql

- - 연락처연락처email: email: [email protected]@unitel.co.kr

blog: blog: visualdb.onblog.comvisualdb.onblog.com

김정선김정선Microsoft SQL Server MVPMicrosoft SQL Server MVP

삼성삼성 SDS MultiCampus SDS MultiCampus 전임강사전임강사

Page 118: select top 10 * from orders

118

추가 자료들추가 자료들

MicrosoftMicrosoft 웹 캐스트웹 캐스트 , SQL Server 2000, SQL Server 2000 에서 실행 계획 읽기에서 실행 계획 읽기http://support.microsoft.com/default.aspx?scid=kb;KO;815337http://support.microsoft.com/default.aspx?scid=kb;KO;815337

SQL Server Quantitative Performance AnalysisSQL Server Quantitative Performance Analysis

http://www.sql-server-performance.com/jc_sql_server_quantative_analhttp://www.sql-server-performance.com/jc_sql_server_quantative_analysis1.aspysis1.asp

Advanced Transact-SQL for SQL Server 2000Advanced Transact-SQL for SQL Server 2000Itzik Ben-Gan, Tom Moreau | ApressItzik Ben-Gan, Tom Moreau | Apress

SQL Server Advanced Programming: SQL Server Advanced Programming: 실무를 고려한실무를 고려한우철웅 우철웅 | | 영진영진 .com.com

Deep Inside T-SQL Deep Inside T-SQL 쿼리 테크닉쿼리 테크닉손호성 손호성 | | 영진영진 .com.com

Programming a Microsoft SQL Server 2000 DatabaseProgramming a Microsoft SQL Server 2000 Database 2073, MOC 2073, MOC 교육 과정교육 과정