जोड़ा SQL Server 2005+
में:
SELECT oo.*
FROM (
SELECT DISTINCT ProductId
FROM Orders
) od
CROSS APPLY
(
SELECT TOP 1 ProductID, Date, CustomerID
FROM Orders oi
WHERE oi.ProductID = od.ProductID
ORDER BY
Date DESC
) oo
नाममात्र, क्वेरी के लिए योजना में शामिल है Nested Loops
।
हालांकि, बाहरी पाश Stream Aggregate
के साथ एक Index Scan
उपयोग करेगा, और भीतरी पाश एक Top
साथ ProductID
के लिए एक Index Seek
शामिल होंगे।
वास्तव में, दूसरा ऑपरेशन लगभग मुफ़्त है, क्योंकि आंतरिक लूप में प्रयुक्त इंडेक्स पेज शायद कैश में रहता है क्योंकि इसका उपयोग बाहरी लूप के लिए किया गया था। ,
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
(строк обработано: 100)
Table 'Orders'. Scan count 103, logical reads 6020, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 234 ms, elapsed time = 125 ms.
जबकि इस एक मात्र SELECT DISTINCT
क्वेरी का परिणाम है:
यहाँ (100
DISTINCT
ProductID
के साथ) 1,000,000
पंक्तियों पर परीक्षा परिणाम है
SELECT od.*
FROM (
SELECT DISTINCT ProductId
FROM Orders
) od
और आँकड़े:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
(строк обработано: 100)
Table 'Orders'. Scan count 3, logical reads 5648, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 250 ms, elapsed time = 125 ms.
जैसा कि हम देख सकते हैं, प्रदर्शन समान है, और CROSS APPLY
केवल 400
अतिरिक्त logical reads
(जो शायद physical
कभी नहीं होगा) लेता है।
यह नहीं देखें कि इस क्वेरी को और बेहतर कैसे करना संभव है।
इसके अलावा इस प्रश्न का लाभ यह है कि यह अच्छी तरह से समानांतर है। आप देख सकते हैं कि CPU
समय elapsed time
से दोगुना है: यह मेरे पुराने Core Duo
पर समांतरता के कारण है।
ए 4-core
CPU
इस क्वेरी को उस समय के आधे में पूरा कर देगा।
खिड़की कार्यों का उपयोग कर समाधान parallelize नहीं:
SELECT od.*
FROM (
SELECT ProductId, Date, CustomerID, ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Date DESC) AS rn
FROM Orders
) od
WHERE rn = 1
, और यहाँ आँकड़े हैं:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
(строк обработано: 100)
Table 'Orders'. Scan count 1, logical reads 5123, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 406 ms, elapsed time = 415 ms.
+1: मैं आप के अंदर मिनट (तारीख) के लिए उपनाम परिभाषित करने की जरूरत लगता है कि आपके गुमनाम शामिल; अन्यथा, यह वही है जो मुझे मिला। यह जानना अच्छा होगा कि इसके लिए बेहतर दृष्टिकोण है या नहीं। – butterchicken
यह क्वेरी गलत जवाब प्राप्त करती है क्योंकि इसमें o1 और firstOrder –
के बीच शामिल होने की तिथि शामिल नहीं है आपको शामिल होने की तिथि शामिल करने की आवश्यकता नहीं है। आपको केवल उप-क्वेरी की उत्पाद आईडी की आवश्यकता है, क्योंकि इसमें न्यूनतम तिथि है। वास्तविक परिणाम लौटने का चयन तिथि लौटाता है। –