SQL सर्वर 2008 R2 क्वेरी ऑप्टिमाइज़र पहेली
हमारे पास दो टेबल हैं, दोनों में 9 मिलियन पंक्तियाँ हैं। 70.000 पंक्तियाँ अलग हैं, अन्य समान हैं।
यह तेजी से, 13 सेकंड है,
select * from bigtable1
except select * from similar_bigtable2
यह आउटपुट को सॉर्ट करता है और तेज़ भी है, साथ ही 13 सेकंड
select * into #q from bigtable1
except select * from similar_bigtable2
select * from #q order by sort_column
जबकि यह काफी धीमा है:
;with q as (
select * from bigtable1
except select * from similar_bigtable2
)
select * from q order by sort_column
और यहां तक कि एक "ट्रिक" जिसे मैं कभी-कभी एसक्यूएल सर्वर को इंगित करने के लिए उपयोग करता हूं कि इसे चलने से पहले क्वेरी के एक निश्चित हिस्से को पहले से निर्धारित करने की आवश्यकता है, काम नहीं करता है और धीमी क्वेरी में भी परिणाम करता है:
;with q as (
select top 100 percent * from bigtable1
except select * from similar_bigtable2
)
select * from q order by sort_column
क्वेरी योजनाओं को देखने के कारण को खोजना मुश्किल नहीं है:
हैशमैच से पहले SQL सर्वर दो तरह की 9 मिलियन पंक्तियों को रखता है, जबकि मैं इसे पसंद करूँगा कि हैशमैच के बाद केवल एक प्रकार की 70.000 पंक्तियों को जोड़ा जाए।
तो सवाल: मैं क्वेरी ऑप्टिमाइज़र को ऐसा करने का निर्देश कैसे दे सकता हूं?
EXCEPT
(जैसे OUTER JOIN
) विकल्प का प्रयास किया है ? मुझे लगता है कि वाक्यविन्यास कम सुविधाजनक है, लेकिन आप सूचकांक के साथ खेलने में सक्षम हो सकते हैं या वहां बेहतर संकेत जोड़ सकते हैं (या आपको इसकी आवश्यकता नहीं हो सकती है)। अब आप जिस विकल्प का उपयोग कर रहे हैं (पहले एक # टेबल में सामान) एक अंतिम रिज़ॉर्ट वर्कअराउंड है, लेकिन कुछ मामलों में ऑप्टिमाइज़र को क्वेरी के दो हिस्सों को पूरी तरह से अलग करने के लिए मजबूर करने का एकमात्र तरीका है जो आप चाहते हैं।