한 행의 존재가 있어야 확인했을 때 나는 종종 읽은 항상 대신 COUNT와의 EXISTS와 함께 할 수.
그러나 몇 가지 최근 시나리오에서 카운트를 사용할 때 성능 향상을 측정했습니다.
패턴은 다음과 같습니다.
LEFT JOIN (
SELECT
someID
, COUNT(*)
FROM someTable
GROUP BY someID
) AS Alias ON (
Alias.someID = mainTable.ID
)
"내부"SQL Server에서 어떤 일이 일어나고 있는지 알려주는 방법에 익숙하지 않으므로 EXISTS에 포함되지 않은 결함이 있었는지 궁금했습니다.
그 현상에 대한 설명이 있습니까?
편집하다:
실행할 수있는 전체 스크립트는 다음과 같습니다.
SET NOCOUNT ON
SET STATISTICS IO OFF
DECLARE @tmp1 TABLE (
ID INT UNIQUE
)
DECLARE @tmp2 TABLE (
ID INT
, X INT IDENTITY
, UNIQUE (ID, X)
)
; WITH T(n) AS (
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master.dbo.spt_values AS S
)
, tally(n) AS (
SELECT
T2.n * 100 + T1.n
FROM T AS T1
CROSS JOIN T AS T2
WHERE T1.n <= 100
AND T2.n <= 100
)
INSERT @tmp1
SELECT n
FROM tally AS T1
WHERE n < 10000
; WITH T(n) AS (
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master.dbo.spt_values AS S
)
, tally(n) AS (
SELECT
T2.n * 100 + T1.n
FROM T AS T1
CROSS JOIN T AS T2
WHERE T1.n <= 100
AND T2.n <= 100
)
INSERT @tmp2
SELECT T1.n
FROM tally AS T1
CROSS JOIN T AS T2
WHERE T1.n < 10000
AND T1.n % 3 <> 0
AND T2.n < 1 + T1.n % 15
PRINT '
COUNT Version:
'
WAITFOR DELAY '00:00:01'
SET STATISTICS IO ON
SET STATISTICS TIME ON
SELECT
T1.ID
, CASE WHEN n > 0 THEN 1 ELSE 0 END AS DoesExist
FROM @tmp1 AS T1
LEFT JOIN (
SELECT
T2.ID
, COUNT(*) AS n
FROM @tmp2 AS T2
GROUP BY T2.ID
) AS T2 ON (
T2.ID = T1.ID
)
WHERE T1.ID BETWEEN 5000 AND 7000
OPTION (RECOMPILE) -- Required since table are filled within the same scope
SET STATISTICS TIME OFF
PRINT '
EXISTS Version:'
WAITFOR DELAY '00:00:01'
SET STATISTICS TIME ON
SELECT
T1.ID
, CASE WHEN EXISTS (
SELECT 1
FROM @tmp2 AS T2
WHERE T2.ID = T1.ID
) THEN 1 ELSE 0 END AS DoesExist
FROM @tmp1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000
OPTION (RECOMPILE) -- Required since table are filled within the same scope
SET STATISTICS TIME OFF
SQL Server 2008R2 (7 64 비트) 에서이 결과를 얻습니다.
COUNT
번역:
표 '# 455F344D'. 스캔 카운트 1, 논리적 읽기 8, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.
표 '# 492FC531'. 스캔 횟수 1, 논리적 읽기 30, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0SQL Server 실행 시간 :
CPU 시간 = 0ms, 경과 시간 = 81ms
EXISTS
번역:
표 '# 492FC531'. 스캔 횟수 1, 논리적 읽기 96, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.
표 '# 455F344D'. 스캔 카운트 1, 논리적 읽기 8, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.SQL Server 실행 시간 :
CPU 시간 = 0ms, 경과 시간 = 76ms