मैंने अक्सर पढ़ा है कि जब किसी को एक पंक्ति के अस्तित्व की जांच करनी होती है तो उसे हमेशा COUNT के बजाय EXISTS के साथ किया जाना चाहिए ।
फिर भी कई हालिया परिदृश्यों में मैंने गणना का उपयोग करते समय प्रदर्शन सुधार को मापा है।
पैटर्न इस प्रकार है:
LEFT JOIN (
SELECT
someID
, COUNT(*)
FROM someTable
GROUP BY someID
) AS Alias ON (
Alias.someID = mainTable.ID
)
मैं एसक्यूएल सर्वर के अंदर "क्या हो रहा है" बताने के तरीकों से परिचित नहीं हूं, इसलिए मैं सोच रहा था कि क्या EXISTS के साथ एक अनियंत्रित दोष था जो मेरे द्वारा किए गए मापों के लिए पूरी तरह से समझ में आता है (क्या EXISTS RBAR हो सकता है?)।
क्या आपके पास उस घटना के बारे में कुछ स्पष्टीकरण है?
संपादित करें:
यहां एक पूरी स्क्रिप्ट है जिसे आप चला सकते हैं:
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 (सात 64 बिट्स) पर मुझे यह परिणाम मिलता है
COUNT
संस्करण:
तालिका '# 455F344D'। स्कैन काउंट 1, लॉजिकल रीड 8, फिजिकल
रीड्स 0, रीड- फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड- फॉरवर्ड रीड्स 0. टेबल '# 492FC531'। स्कैन काउंट 1, लॉजिकल रीड 30, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।SQL सर्वर निष्पादन समय:
CPU समय = 0 ms, बीता समय = 81 ms।
EXISTS
संस्करण:
टेबल '# 492FC531'। स्कैन काउंट 1, लॉजिकल रीड 96, फिजिकल
रीड्स 0, रीड- फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड- फॉरवर्ड रीड्स 0. टेबल '# 455F344D'। स्कैन काउंट 1, लॉजिकल रीड 8, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।SQL सर्वर निष्पादन समय:
CPU समय = 0 ms, बीता हुआ समय = 76 ms।