नोट:यह पोस्ट मूल रूप से केवल हमारी ईबुक, SQL सर्वर के लिए उच्च प्रदर्शन तकनीक, खंड 3 में प्रकाशित हुई थी। आप हमारी ई-पुस्तकों के बारे में यहां जान सकते हैं।
तीन साल पहले, मैंने SQL सर्वर में कर्सर विकल्पों पर एक पोस्ट लिखी थी, और आपको डिफ़ॉल्ट को ओवरराइड क्यों करना चाहिए:
- विभिन्न कर्सर विकल्पों का क्या प्रभाव हो सकता है?
मैं इसे दोहराने के लिए एक अनुवर्ती पोस्ट करना चाहता था - जबकि आपको कभी भी चूक को स्वीकार नहीं करना चाहिए - आपको वास्तव में यह सोचना चाहिए कि आपके परिदृश्य पर कौन से विकल्प सबसे अधिक लागू होते हैं। मैं उस पोस्ट पर टिप्पणियों में आने वाली कुछ वस्तुओं को भी स्पष्ट करना चाहता था।
एंड्रयू केली ने एक अच्छी बात कही, और वह है STATIC
कर्सर परिणामों की एक बार की प्रतिलिपि बनाता है, उन्हें tempdb में डालता है, और फिर किसी भी समवर्ती मुद्दों से बचा जाता है जो DYNAMIC
को प्रभावित कर सकते हैं कर्सर. सभी मामलों में एक विकल्प दूसरे पर स्पष्ट विजेता नहीं है; उदाहरण के लिए, आपके पास बहुत से कर्सर (या बहुत बड़े परिणाम वाले कर्सर) और/या पहले से ही अधिक बोझ वाले tempdb हो सकते हैं और वहां कोई अतिरिक्त तनाव नहीं लेना चाहते हैं। लेकिन यह परीक्षण के योग्य है।
फैबियानो ने भी एक महान मुद्दा उठाया कि दोनों DYNAMIC
और FAST_FORWARD
कर्सर कर सकते हैं हेलोवेन समस्या के प्रति संवेदनशील हों (पॉल व्हाइट द्वारा 4-भाग श्रृंखला में चर्चा की गई, यहां से शुरू)। पॉल ने यह भी टिप्पणी की कि FAST_FORWARD
हो सकता है कि समस्या के प्रति संवेदनशील न हो, इस पर निर्भर करता है कि क्या अनुकूलक ने एक स्थिर या गतिशील योजना को चुना है (Microsoft के मार्क फ्रीडमैन इसके बारे में यहां बहुत विस्तार से बताते हैं)।
अंत में, मैं यह बताना चाहता था कि सभी डिफ़ॉल्ट कर्सर समान नहीं बनाए जाते हैं। मैंने कुछ परीक्षण चलाए और जाँच की कि कैसे SQL सर्वर ने विभिन्न परिदृश्यों के तहत कर्सर विकल्प सेट करने का निर्णय लिया (sys.dm_exec_cursors
का उपयोग करके सत्यापित किया गया) गतिशील प्रबंधन समारोह)। कोड बहुत आसान है:
DECLARE c CURSOR FOR [...blah blah...]; SELECT properties FROM sys.dm_exec_cursors(@@SPID);
मेरे द्वारा परीक्षण किए गए परिदृश्यों के परिणाम यहां दिए गए हैं:
कर्सर क्वेरी पर आधारित है... | प्रकार | संगामिति | स्कोप |
---|---|---|---|
एक स्थिरांक (FOR SELECT 1 या FOR SELECT SYSDATETIME() ) | स्नैपशॉट | केवल पढ़ने के लिए | वैश्विक |
एक #temp / ##temp तालिका | गतिशील | आशावादी | वैश्विक |
एक उपयोगकर्ता तालिका / दृश्य | गतिशील | आशावादी | वैश्विक |
एक कैटलॉग दृश्य / DMV | स्नैपशॉट | केवल पढ़ने के लिए | वैश्विक |
एक ज्वाइन #tmp -> यूजर टेबल / व्यू | गतिशील | आशावादी | वैश्विक |
a join #tmp -> कैटलॉग व्यू / DMV | स्नैपशॉट | केवल पढ़ने के लिए | वैश्विक |
एक उपयोगकर्ता तालिका / दृश्य में शामिल हों -> कैटलॉग दृश्य / DMV | स्नैपशॉट | केवल पढ़ने के लिए | वैश्विक |
क्रेडिट जहां देय है - यह जांच स्टैक ओवरफ्लो पर जेरोएन मोस्टर्ट के एक उत्तर से शुरू हुई थी।
इसलिए आपको पता होना चाहिए कि आपके कर्सर के लिए डिफ़ॉल्ट विकल्प, यदि आप उन्हें ओवरराइड नहीं करते हैं, तो कर्सर के नीचे की क्वेरी के आधार पर भिन्न हो सकते हैं। यदि आप किसी भी या सभी मामलों में एक विशिष्ट व्यवहार की अपेक्षा कर रहे हैं, तो अपने इच्छित विकल्पों को स्पष्ट रूप से निर्दिष्ट करने की आदत डालें।
लेकिन असल में बात यह है...
…कर्सर का उपयोग बंद करो। आज वास्तव में बहुत कम समस्याएं हैं जहां सबसे अच्छा समाधान एक कर्सर है, खासकर यदि आप SQL सर्वर 2012 या बेहतर पर हैं - जहां कर्सर द्वारा पारंपरिक रूप से हल की जाने वाली हर समस्या को विंडो फ़ंक्शंस में एन्हांसमेंट का उपयोग करके हल किया जा सकता है। यदि आपको अभी भी लगता है कि आपको कर्सर का उपयोग करने की आवश्यकता है, तो कृपया इस पोस्ट और इसके पूर्ववर्ती में सलाह लें कि यह निर्धारित करें कि आपको किन विकल्पों का उपयोग करना चाहिए।