निम्न स्कीमा और उदाहरण के लिए डेटा
CREATE TABLE T
(
A INT NULL,
B INT NOT NULL IDENTITY,
C CHAR(8000) NULL,
UNIQUE CLUSTERED (A, B)
)
INSERT INTO T
(A)
SELECT NULLIF(( ( ROW_NUMBER() OVER (ORDER BY @@SPID) - 1 ) / 1003 ), 0)
FROM master..spt_values
एक आवेदन 1,000 पंक्ति विखंडू में अनुक्रमित क्रम में इस तालिका से पंक्तियों को संसाधित कर रहा है।
पहली 1,000 पंक्तियाँ निम्नलिखित क्वेरी से प्राप्त की जाती हैं।
SELECT TOP 1000 *
FROM T
ORDER BY A, B
उस सेट की अंतिम पंक्ति नीचे है
+------+------+
| A | B |
+------+------+
| NULL | 1000 |
+------+------+
क्या कोई प्रश्न लिखने का कोई तरीका है जो सिर्फ उस समग्र सूचकांक कुंजी में खोजता है और फिर 1000 पंक्तियों के अगले भाग को प्राप्त करने के लिए इसका अनुसरण करता है?
/*Pseudo Syntax*/
SELECT TOP 1000 *
FROM T
WHERE (A, B) is_ordered_after (@A, @B)
ORDER BY A, B
मैंने अब तक सबसे कम पढ़े जाने की संख्या 1020 है, लेकिन लगता है कि क्वेरी बहुत दूर है। क्या समान या बेहतर दक्षता का एक सरल तरीका है? शायद एक है कि यह सब एक सीमा में करने के लिए प्रबंधित करता है?
DECLARE @A INT = NULL, @B INT = 1000
;WITH UnProcessed
AS (SELECT *
FROM T
WHERE ( EXISTS(SELECT A
INTERSECT
SELECT @A)
AND B > @B )
UNION ALL
SELECT *
FROM T
WHERE @A IS NULL AND A IS NOT NULL
UNION ALL
SELECT *
FROM T
WHERE A > @A
)
SELECT TOP 1000 *
FROM UnProcessed
ORDER BY A,
B
एफडब्ल्यूआईडब्ल्यू: यदि स्तंभ A
बनाया गया है NOT NULL
और एक समान मूल्य का -1
उपयोग किया जाता है, तो इसके बजाय समान निष्पादन योजना निश्चित रूप से सरल लगती है
लेकिन योजना में एकल तलाश ऑपरेटर अभी भी एक ही सन्निहित सीमा में ढहने के बजाय दो तलाश करता है और तार्किक रीड बहुत अधिक हैं इसलिए मुझे संदेह है कि शायद यह बहुत अच्छा है जितना इसे मिलेगा?
(NULL, 1000 )
@A
, यह शून्य है या नहीं, ऐसा लगता है कि यह स्कैन नहीं करता है। लेकिन मैं यह नहीं समझ सकता कि क्या योजनाएँ आपकी क्वेरी से बेहतर हैं। फिडल -2
NULL
मूल्य हमेशा पहले होते हैं। (इसके विपरीत मान लिया गया।) फिडल