/* 조인 순서와 성능 */
/*
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 |