/* 조인 순서와 성능 */

 

/*

1. NL 조인의 순서

             NL 조인은 랜덤 액세스 위주로 수행되므로, 대부분 후행 테이블을 액세스하는 횟수에 따라 성능이 달라진다.

*/

 

--// 큰 집합을 먼저 액세스했을 때

USE Northwind

GO

 

EXEC sp_helpindex 'Orders';

EXEC sp_helpindex '[Order Details]';

 

SELECT COUNT(*) FROM Orders;

GO

--830

 

SELECT COUNT(*) FROM [Order Details];

GO

--2155

 

SET STATISTICS PROFILE ON

SET STATISTICS IO ON

SET STATISTICS TIME ON

GO

 

SELECT *

FROM [Order Details] b, Orders a

WHERE a.OrderID = b.OrderID

OPTION (FORCE ORDER, LOOP JOIN)

GO

--(2155개 행이 영향을 받음)

--테이블 'Orders'. 검색 수 0, 논리적 읽기 수 4453, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Order Details'. 검색 수 1, 논리적 읽기 수 11, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

--Rows   Executes             StmtText

--2155   1           SELECT * FROM [Order Details] b, Orders a WHERE a.OrderID = b.OrderID OPTION (FORCE ORDER, LOOP JOIN)

--2155   1             |--Nested Loops(Inner Join, OUTER REFERENCES:([b].[OrderID], [Expr1004]) WITH UNORDERED PREFETCH)

--2155   1                  |--Clustered Index Scan(OBJECT:([Northwind].[dbo].[Order Details].[PK_Order_Details] AS [b]))

--2155   2155            |--Clustered Index Seek(OBJECT:([Northwind].[dbo].[Orders].[PK_Orders] AS [a]), SEEK:([a].[OrderID]=[Northwind].[dbo].[Order Details].[OrderID] as [b].[OrderID]) ORDERED FORWARD)

 

--양쪽 테이블 모두 클러스터형 인덱스로 구성되어 있으므로 북마크 룩업에 의한 랜덤 액세스가 추가로 발생하지는 않는다.

 

 

--//작은 집합을 먼저 액세스했을 때

SELECT *

FROM Orders a, [Order Details] b

WHERE a.OrderID = b.OrderID

OPTION (FORCE ORDER, LOOP JOIN)

GO

--(2155개 행이 영향을 받음)

--테이블 'Order Details'. 검색 수 830, 논리적 읽기 수 1672, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Orders'. 검색 수 1, 논리적 읽기 수 22, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

--Rows   Executes             StmtText

--2155   1           SELECT * FROM Orders a, [Order Details] b WHERE a.OrderID = b.OrderID OPTION (FORCE ORDER, LOOP JOIN)

--2155   1             |--Nested Loops(Inner Join, OUTER REFERENCES:([a].[OrderID]))

--830     1                  |--Clustered Index Scan(OBJECT:([Northwind].[dbo].[Orders].[PK_Orders] AS [a]))

--2155   830              |--Clustered Index Seek(OBJECT:([Northwind].[dbo].[Order Details].[PK_Order_Details] AS [b]), SEEK:([b].[OrderID]=[Northwind].[dbo].[Orders].[OrderID] as [a].[OrderID]) ORDERED FORWARD)

 

 

/* 큰 집합을 먼저 액세스했을 때는 페이지 I/O가 총 4,464(=4,453+11)개 발생했고,

작은 집합을 먼저 액세스했을 때는 페이지 I/O 1,694(=1,672+22)개 발생했다.

NL 조인은 작은 집합을 먼저 액세스하는 게 '일반적으로' 유리하다.

클러스터형 여부가 조인 순서의 효율성에 영향을 미치기도 하지만, 양쪽 테이블에 같은 조건의 인덱스가 있다면 작은 쪽을 먼저 액세스하는 게 유리하다 */

 

 

/*

2. 해시 조인의 순서

해시 조인은 해시 테이블을 구성하는 Build Input의 크기가 성능에 큰 영향을 미친다.

Build Input이 가용 메모리보다 작으면 해시 테이블을 메모리 안에 생성하게 된다.

이렇게 메모리 안에서 한 번에 처리되는 방식을 인-메모리 해시 조인이라고 한다.

만약 Build Input이 가용 메모리를 초과하면 유예(Grace) 해시 조인 또는 재귀(Recursive) 해시 조인으로 수행되는데,

-메모리 해시 조인과는 달리 대상 집합을 분할하여 단계적으로 조인하는 복잡한 과정을 거치게 된다.

*/

 

--//테이블 두 개를 해시 조인할 때

--해시 조인은 양쪽 테이블을 각각 한 번만 액세스하므로 조인 순서를 바꿔도 테이블 검색 수와 논리적 읽기 수는 달라지지 않는다.

--따라서 해시 조인은 CPU와 경과 시간을 기준으로 성능 차이를 비교해야 한다. 조인에 참여하는 두 집합의 크기가 극단적으로

--달라야 성능차이를 확실히 느낄 수 있을 것이다.

 

--=====================================================

USE jwjung

GO

ALTER DATABASE jwjung ADD FILE

(

             name = jwjung_dat2

             ,filename = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\jwjung_dat2.ndf'

             ,size = 100mb

             ,maxsize = 500mb

             ,filegrowth = 50mb

)

GO

 

SELECT TOP 100000

             identity(int, 1, 1) as 고객id

             , CONVERT(VARCHAR(1),

                           CASE WHEN ABS(a.id)%3 = 0 THEN 'A'

                                                                  WHEN ABS(a.id)%3 = 1 THEN 'B'

                                                                  WHEN ABS(a.id)%3 = 2 THEN 'C'

                           END) as 거주지역코드

             , a.*

INTO 고객

FROM master.dbo.syscolumns a

                           , master.dbo.sysindexes b

GO

 

SELECT TOP 5000000

             identity(int, 1, 1) as 계약id, a.고객id

             , CONVERT(DECIMAL(12, 2), b.id) as 계약금액

             , CONVERT(DECIMAL(12, 2), b.id) as 납입금액

             , CONVERT(VARCHAR(1),

                           CASE WHEN b.id%5 IN (0, 1) THEN '1'

                                                     WHEN b.id%5 IN (2, 3) THEN '2'

                           ELSE '9'

                           END) as 계약상태코드

             , b.*

INTO 계약

FROM 고객 a, (SELECT TOP 50 * FROM master.dbo.syscolumns) b

GO

--=====================================================

 

 

SELECT b.거주지역코드, SUM(a.계약금액), SUM(a.납입금액)

FROM 계약 a, 고객 b

WHERE a.고객id = b.고객id

GROUP BY b.거주지역코드

OPTION (FORCE ORDER, HASH JOIN)

GO

 

--(3개 행이 영향을 받음)

--테이블 '계약'. 검색 수 5, 논리적 읽기 수 82070, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '고객'. 검색 수 5, 논리적 읽기 수 1418, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

--Rows   Executes             StmtText

--3         1           SELECT b.거주지역코드, SUM(a.계약금액), SUM(a.납입금액) FROM 계약 a, 고객 b WHERE a.고객id = b.고객id GROUP BY b.거주지역코드 OPTION (FORCE ORDER, HASH JOIN)

--0         0             |--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [globalagg1009]=(0) THEN NULL ELSE [globalagg1011] END, [Expr1007]=CASE WHEN [globalagg1013]=(0) THEN NULL ELSE [globalagg1015] END))

--3         1                  |--Stream Aggregate(GROUP BY:([b].[거주지역코드]) DEFINE:([globalagg1009]=SUM([partialagg1008]), [globalagg1011]=SUM([partialagg1010]), [globalagg1013]=SUM([partialagg1012]), [globalagg1015]=SUM([partialagg1014])))

--12       1                       |--Sort(ORDER BY:([b].[거주지역코드] ASC))

--12       1                            |--Parallelism(Gather Streams)

--12       4                                 |--Hash Match(Partial Aggregate, HASH:([b].[거주지역코드]), RESIDUAL:([jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] = [jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드]) DEFINE:([partialagg1008]=COUNT_BIG([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1010]=SUM([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1012]=COUNT_BIG([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액]), [partialagg1014]=SUM([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액])))

--5000000          4                                      |--Hash Match(Inner Join, HASH:([a].[고객id])=([b].[고객id]))

--5000000          4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([a].[고객id]))

--5000000          4                                           |    |--Table Scan(OBJECT:([jwjung].[dbo].[계약] AS [a]))

--100000            4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([b].[고객id]))

--100000            4                                                |--Table Scan(OBJECT:([jwjung].[dbo].[고객] AS [b]))

 

--   CPU 시간 = 14195밀리초, 경과 시간 = 3809밀리초

 

 

SELECT b.거주지역코드, SUM(a.계약금액), SUM(a.납입금액)

FROM 고객 b, 계약 a

WHERE a.고객id = b.고객id

GROUP BY b.거주지역코드

OPTION (FORCE ORDER, HASH JOIN)

GO

--(3개 행이 영향을 받음)

--테이블 '고객'. 검색 수 5, 논리적 읽기 수 1418, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '계약'. 검색 수 5, 논리적 읽기 수 82070, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

--Rows   Executes             StmtText

--3         1           SELECT b.거주지역코드, SUM(a.계약금액), SUM(a.납입금액) FROM 고객 b, 계약 a WHERE a.고객id = b.고객id GROUP BY b.거주지역코드 OPTION (FORCE ORDER, HASH JOIN)

--0         0             |--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [globalagg1009]=(0) THEN NULL ELSE [globalagg1011] END, [Expr1007]=CASE WHEN [globalagg1013]=(0) THEN NULL ELSE [globalagg1015] END))

--3         1                  |--Stream Aggregate(GROUP BY:([b].[거주지역코드]) DEFINE:([globalagg1009]=SUM([partialagg1008]), [globalagg1011]=SUM([partialagg1010]), [globalagg1013]=SUM([partialagg1012]), [globalagg1015]=SUM([partialagg1014])))

--12       1                       |--Sort(ORDER BY:([b].[거주지역코드] ASC))

--12       1                            |--Parallelism(Gather Streams)

--12       4                                 |--Hash Match(Partial Aggregate, HASH:([b].[거주지역코드]), RESIDUAL:([jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] = [jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드]) DEFINE:([partialagg1008]=COUNT_BIG([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1010]=SUM([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1012]=COUNT_BIG([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액]), [partialagg1014]=SUM([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액])))

--5000000          4                                      |--Hash Match(Inner Join, HASH:([b].[고객id])=([a].[고객id]))

--100000            4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([b].[고객id]))

--100000            4                                           |    |--Table Scan(OBJECT:([jwjung].[dbo].[고객] AS [b]))

--5000000          4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([a].[고객id]))

--5000000          4                                                |--Table Scan(OBJECT:([jwjung].[dbo].[계약] AS [a]))

 

--CPU 시간 = 14086밀리초, 경과 시간 = 3727밀리초

 

 

--해시 버킷에 중복된 값이 얼마나 많으냐에 따라 해시 조인의 효율이 달라지기도 하지만,

--대부분 작은 집합을 먼저 액세스하는 게 유리하다.

 

 

/*

3. 테이블 세 개 이상을 해시 조인할 때

해시 조인할 때는 작은 집합을 먼저 액세스하는 게 유리하다. 그러면 1:M:1 관계를 맺고 있는 테이블 세 개를 해시 조인하고자 할 때는

어떤 순서가 유리할까? 집합 크기를 확실히 줄일 수 있는 검색조건이 있으면 그 조건이 먼저 적용되도록 조인 순서를 조정하면 된다.

그러나 별다른 검색조건이 없어서 어떻게 조인해도 집합 크기가 줄어들지 않는다면 순서를 결정하기가 쉽지 않다.

*/

 

USE jwjung

GO

 

SELECT TOP 10

             IDENTITY(INT, 0, 1) as 코드id

             , CONVERT(VARCHAR(1), 'Y') as 사용여부

INTO 코드

FROM master.dbo.syscolumns a

GO

 

ALTER TABLE 코드 ADD CONSTRAINT 코드_pk PRIMARY KEY CLUSTERED (코드id)

GO

 

SELECT b.거주지역코드, a.계약상태코드, SUM(a.계약금액), SUM(a.납입금액)

FROM 코드 c, 계약 a, 고객 b

WHERE a.고객id = b.고객id

             AND a.계약상태코드 = c.코드id

             AND c.사용여부 = 'Y'

GROUP BY b.거주지역코드, a.계약상태코드

OPTION (FORCE ORDER, HASH JOIN)

GO

 

--CPU 시간 = 26785밀리초, 경과 시간 = 7980밀리초

 

--(6개 행이 영향을 받음)

--테이블 '코드'. 검색 수 1, 논리적 읽기 수 2, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '계약'. 검색 수 5, 논리적 읽기 수 82070, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '고객'. 검색 수 5, 논리적 읽기 수 1418, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

--Rows   Executes             StmtText

--6         1           SELECT b.거주지역코드, a.계약상태코드, SUM(a.계약금액), SUM(a.납입금액) FROM 코드 c, 계약 a, 고객 b WHERE a.고객id = b.고객id             AND a.계약상태코드 = c.코드id AND c.사용여부 = 'Y' GROUP BY b.거주지역코드, a.계약상태코드 OPTION (FORCE ORDER, HASH JOIN)

--0         0             |--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [globalagg1012]=(0) THEN NULL ELSE [globalagg1014] END, [Expr1009]=CASE WHEN [globalagg1016]=(0) THEN NULL ELSE [globalagg1018] END))

--6         1                  |--Stream Aggregate(GROUP BY:([a].[계약상태코드], [b].[거주지역코드]) DEFINE:([globalagg1012]=SUM([partialagg1011]), [globalagg1014]=SUM([partialagg1013]), [globalagg1016]=SUM([partialagg1015]), [globalagg1018]=SUM([partialagg1017])))

--24       1                       |--Sort(ORDER BY:([a].[계약상태코드] ASC, [b].[거주지역코드] ASC))

--24       1                            |--Parallelism(Gather Streams)

--24       4                                 |--Hash Match(Partial Aggregate, HASH:([b].[거주지역코드], [a].[계약상태코드]), RESIDUAL:([jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] = [jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] AND [jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드] = [jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드]) DEFINE:([partialagg1011]=COUNT_BIG([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1013]=SUM([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1015]=COUNT_BIG([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액]), [partialagg1017]=SUM([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액])))

--5000000          4                                      |--Hash Match(Inner Join, HASH:([a].[고객id])=([b].[고객id]))

--5000000          4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([a].[고객id]))

--5000000          4                                           |    |--Hash Match(Inner Join, HASH:([c].[코드id])=([Expr1010]), RESIDUAL:([Expr1010]=[jwjung].[dbo].[코드].[코드id] as [c].[코드id]))

--40       4                                           |         |--Parallelism(Distribute Streams, Broadcast Partitioning)

--10       1                                           |         |    |--Clustered Index Scan(OBJECT:([jwjung].[dbo].[코드].[코드_pk] AS [c]), WHERE:([jwjung].[dbo].[코드].[사용여부] as [c].[사용여부]='Y'))

--0         0                                           |         |--Compute Scalar(DEFINE:([Expr1010]=CONVERT_IMPLICIT(int,[jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드],0)))

--5000000          4                                           |              |--Table Scan(OBJECT:([jwjung].[dbo].[계약] AS [a]))

--100000            4                                           |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([b].[고객id]))

--100000            4                                                |--Table Scan(OBJECT:([jwjung].[dbo].[고객] AS [b]))

 

--코드 테이블에서 추출한 10건으로 해시 테이블을 생성하고 계약 테이블을 스캔하면서 해시 테이블을 500만 번 탐색했다.

--두 테이블이 코드->계약의 이상적인 순서로 조인하여 500만 건짜리 중간 집합을 만들었다.

--이 집합으로 다시 해시 테이블을 생성하고 고객 테이블을 스캔하면서(두 번째로 만들어진) 해시 테이블을 10만 번 탐색했다.

--이번에는 조인 순서에 문제가 있다. 500만 건으로 해시 테이블을 생성하고서 10만 건으로 이를 탐색한 것이다.

--그렇다고 고객->계약->코드 순서로 조인하면 더 비효율적이다.(테스트결과)

 

--효율적인 순서로 조인하도록 쿼리를 변경하고서 실행

SELECT x.거주지역코드, x.계약상태코드, SUM(x.계약금액), SUM(x.납입금액)

FROM 코드 c,

             (

             SELECT b.거주지역코드, a.계약상태코드, a.계약금액, a.납입금액

             FROM 고객 b INNER HASH JOIN 계약 a

                           ON a.고객id = b.고객id

             ) x

WHERE x.계약상태코드 = c.코드id

             AND c.사용여부 = 'Y'

GROUP BY x.거주지역코드, x.계약상태코드

OPTION (FORCE ORDER, HASH JOIN)

GO

 

--Rows   Executes             StmtText

--6         1           SELECT x.거주지역코드, x.계약상태코드, SUM(x.계약금액), SUM(x.납입금액) FROM 코드 c, (             SELECT b.거주지역코드, a.계약상태코드, a.계약금액, a.납입금액 FROM 고객 b INNER HASH JOIN 계약 a        ON a.고객id = b.고객id) x WHERE x.계약상태코드 = c.코드id AND c.사용여부 = 'Y' GROUP BY x.거주지역코드, x.계약상태코드 OPTION (FORCE ORDER, HASH JOIN)

--0         0             |--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [globalagg1012]=(0) THEN NULL ELSE [globalagg1014] END, [Expr1009]=CASE WHEN [globalagg1016]=(0) THEN NULL ELSE [globalagg1018] END))

--6         1                  |--Stream Aggregate(GROUP BY:([a].[계약상태코드], [b].[거주지역코드]) DEFINE:([globalagg1012]=SUM([partialagg1011]), [globalagg1014]=SUM([partialagg1013]), [globalagg1016]=SUM([partialagg1015]), [globalagg1018]=SUM([partialagg1017])))

--24       1                       |--Sort(ORDER BY:([a].[계약상태코드] ASC, [b].[거주지역코드] ASC))

--24       1                            |--Parallelism(Gather Streams)

--24       4                                 |--Hash Match(Partial Aggregate, HASH:([b].[거주지역코드], [a].[계약상태코드]), RESIDUAL:([jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] = [jwjung].[dbo].[고객].[거주지역코드] as [b].[거주지역코드] AND [jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드] = [jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드]) DEFINE:([partialagg1011]=COUNT_BIG([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1013]=SUM([jwjung].[dbo].[계약].[계약금액] as [a].[계약금액]), [partialagg1015]=COUNT_BIG([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액]), [partialagg1017]=SUM([jwjung].[dbo].[계약].[납입금액] as [a].[납입금액])))

--5000000          4                                      |--Hash Match(Inner Join, HASH:([c].[코드id])=([Expr1010]), RESIDUAL:([Expr1010]=[jwjung].[dbo].[코드].[코드id] as [c].[코드id]))

--40       4                                           |--Parallelism(Distribute Streams, Broadcast Partitioning)

--10       1                                           |    |--Clustered Index Scan(OBJECT:([jwjung].[dbo].[코드].[코드_pk] AS [c]), WHERE:([jwjung].[dbo].[코드].[사용여부] as [c].[사용여부]='Y'))

--0         0                                           |--Compute Scalar(DEFINE:([Expr1010]=CONVERT_IMPLICIT(int,[jwjung].[dbo].[계약].[계약상태코드] as [a].[계약상태코드],0)))

--5000000          4                                                |--Hash Match(Inner Join, HASH:([b].[고객id])=([a].[고객id]))

--100000            4                                                     |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([b].[고객id]))

--100000            4                                                     |    |--Table Scan(OBJECT:([jwjung].[dbo].[고객] AS [b]))

--5000000          4                                                     |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([a].[고객id]))

--5000000          4                                                          |--Table Scan(OBJECT:([jwjung].[dbo].[계약] AS [a]))

 

--(6개 행이 영향을 받음)

--테이블 '코드'. 검색 수 1, 논리적 읽기 수 2, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '고객'. 검색 수 5, 논리적 읽기 수 1418, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 '계약'. 검색 수 5, 논리적 읽기 수 82070, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.

 

-- CPU 시간 = 21808밀리초, 경과 시간 = 5803밀리초

 

SET STATISTICS PROFILE OFF

SET STATISTICS IO OFF

SET STATISTICS TIME OFF

GO

 

'연구개발 > DBA' 카테고리의 다른 글

정렬의 최적화 (02.인덱스 정렬을 제거)  (0) 2012.01.24
정렬의 최적화 (01.정렬이 발생하는 경우)  (0) 2012.01.24
조인 join  (0) 2012.01.20
면접질의  (0) 2012.01.20
데이터베이스 백업과 복원  (0) 2012.01.20

+ Recent posts