दिलचस्प पोस्ट
Vim में टेक्स्ट चिपकाने पर ऑटो इंडेंट बंद करना एक विशिष्ट शाखा से निपटने के लिए जीआईटी के बाद प्राप्त हुक लिखना UIWebView में ObjectiveC के लिए जावास्क्रिप्ट से एक सूचना भेजें विंडोज़ पर एक्सेल वीबीए में, पार्स किए गए जेएसओएन व्हेरिएबल्स के लिए वैसे भी यह जेस्क्रिप्टटाइजइन्फो क्या है? अनचाहे त्रुटि: अपरिवर्तनीय उल्लंघन: तत्व का प्रकार अमान्य है: एक स्ट्रिंग (अंतर्निहित घटकों के लिए) या कक्षा / फ़ंक्शन की अपेक्षा की गई, लेकिन उसे मिला: ऑब्जेक्ट ओपनसीवी वस्तुतः कैमरा घूर्णन / पक्षी की आंखों के दृश्य के लिए अनुवाद करना फिबोनैकी एल्गोरिथ्म को पुनर्संरचना बाश में कई संख्याओं के लिए केस का उपयोग करना आईआईएस 7 एपलीकेशन पूल में नेट फ्रेमवर्क 4.5 संस्करण कैसे सेट करें I संक्षिप्त वेक्टर पायथन में जोड़ने? एनएमएमएम यूएनएमईटी पीयर डिपाण्डैन्सी को कैसे हल करें स्पार्क डेटाफ्रेम को लोचदार खोज में सहेजें – प्रकार अपवाद को नियंत्रित नहीं कर सकता एसएमटीपी का इस्तेमाल करने वाले इरादों के बिना एंड्रॉइड में मेल भेजना क्यों नहीं std :: cout आउटपुट पूरी तरह से गायब हो जाता है जब यह नल को भेजा जाता है जावा में सूची के लिए मानचित्र को कैसे रूपांतरित करना है?

SQL सर्वर में कर्सर का उपयोग करने के लिए खराब अभ्यास क्यों माना जाता है?

मुझे कुछ प्रदर्शन कारणों से वापस SQL ​​7 दिनों का पता था, लेकिन क्या समान समस्याएँ अभी भी SQL Server 2005 में मौजूद हैं? अगर मेरे पास एक संग्रहीत कार्यविधि में एक परिणाम है जो मैं व्यक्तिगत रूप से कार्य करना चाहता हूं, तो क्या कर्सर अभी भी खराब विकल्प हैं? यदि हां, तो क्यों?

Solutions Collecting From Web of "SQL सर्वर में कर्सर का उपयोग करने के लिए खराब अभ्यास क्यों माना जाता है?"

क्योंकि कर्सर मेमोरी लेते हैं और ताले बनाते हैं।

जो वास्तव में आप कर रहे हैं वह सेट-आधारित तकनीक को गैर-निर्धारित आधारित कार्यक्षमता में लागू करने का प्रयास कर रहा है। और, सभी निष्पक्षता में, मुझे कहना चाहिए कि कर्सर का उपयोग होता है, लेकिन उन पर फिक्र किया जाता है क्योंकि सेट-आधारित समाधानों का उपयोग करने के लिए उपयोग नहीं किए जाने वाले बहुत से लोग सेट-आधारित समाधान का पता लगाने के बजाय कर्सर का उपयोग करते हैं।

लेकिन, जब आप कर्सर खोलते हैं, तो आप मूल रूप से उन पंक्तियों को स्मृति में लोड कर रहे हैं और लॉकिंग कर रहे हैं, संभावित ब्लॉकों को बनाते हैं। फिर, जैसा कि आप कर्सर के माध्यम से चक्र करते हैं, आप अन्य तालिकाओं में परिवर्तन कर रहे हैं और अभी भी सभी स्मृति और कर्सर के ताले को खोलकर खुले हैं I

जिन सभी के पास अन्य उपयोगकर्ताओं के लिए प्रदर्शन समस्याएं पैदा करने की क्षमता है।

इसलिए, एक सामान्य नियम के रूप में, कर्सर को सफ़ल किया जाता है। खासकर अगर समस्या का समाधान करने में यह पहला समाधान आया है।

एसक्यूएल के बारे में उपर्युक्त टिप्पणियां एक सेट-आधारित वातावरण हैं ये सभी सत्य हैं। हालांकि कई बार जब पंक्ति-दर-पंक्ति के संचालन उपयोगी होते हैं मेटाडेटा और गतिशील-एसक्यूएल के संयोजन पर विचार करें

एक बहुत ही सरल उदाहरण के रूप में, मेरे पास एक टेबल में 100+ रिकॉर्ड हैं, जो तालिका के नाम को परिभाषित करता है, जिसे मैं प्रतिलिपि / छांटना चाहूंगा / जो भी हो कौन सा सबसे अच्छा है? क्या मैं करने के लिए एसक्यूएल hardcoding करने की आवश्यकता है? या इस परिणाम के माध्यम से दोबारा और गतिशील-एसक्यूएल (sp_executesql) का उपयोग करने के लिए आपरेशनों का उपयोग करें?

सेट-आधारित एसक्यूएल का उपयोग करके उपरोक्त उद्देश्य प्राप्त करने का कोई तरीका नहीं है

तो, कर्सर या थोड़ी देर लूप (छद्म कर्सर) का उपयोग करने के लिए?

जब तक आप सही विकल्प का उपयोग करते हैं तब तक SQL कर्सर ठीक होते हैं:

INSENTITIVE आपके परिणाम सेट की एक अस्थायी प्रतिलिपि बना देगा (आपको अपने छद्म कर्सर के लिए ऐसा करने से बचाना)।

READ_ONLY यह सुनिश्चित करेगा कि अंतर्निहित परिणाम सेट पर कोई लॉक नहीं रखे गए हैं। अंतर्निहित परिणाम सेट में होने वाले परिवर्तन बाद के फैले में दिखाई देंगे (जैसे कि आपके छद्म कर्सर से शीर्ष 1 हो रहा है)।

FAST_FORWARD एक अनुकूलित अग्रेषित-केवल, केवल पढ़ने के लिए कर्सर बनाएगा।

सभी कर्सर को बुराई के रूप में पेश करने से पहले उपलब्ध विकल्पों के बारे में पढ़ें

कर्सर के आसपास एक काम है जो हर बार मुझे एक की आवश्यकता होती है।

मैं इसमें एक पहचान कॉलम के साथ एक टेबल वैरिएबल बना रहा हूँ

मुझे इसके साथ काम करने के लिए सभी डेटा डालें।

फिर एक काउंटर वेरिएबल के साथ कुछ देर ब्लॉक करें और उस तालिका का चयन करें जिसे मैं तालिका वैरिएबल से चुनता है जहां एक पहचान का कॉलम काउंटर से मेल खाता है।

इस तरह मैं कुछ भी नहीं लॉक और बहुत कम मेमोरी का इस्तेमाल करता हूं और इसके सुरक्षित, मैं स्मृति भ्रष्टाचार के साथ कुछ भी नहीं खोऊंगा या ऐसा कुछ।

और ब्लॉक कोड को देखने और संभाल करना आसान है।

यह एक सरल उदाहरण है:

 DECLARE @TAB TABLE(ID INT IDENTITY, COLUMN1 VARCHAR(10), COLUMN2 VARCHAR(10)) DECLARE @COUNT INT, @MAX INT, @CONCAT VARCHAR(MAX), @COLUMN1 VARCHAR(10), @COLUMN2 VARCHAR(10) SET @COUNT = 1 INSERT INTO @TAB VALUES('TE1S', 'TE21') INSERT INTO @TAB VALUES('TE1S', 'TE22') INSERT INTO @TAB VALUES('TE1S', 'TE23') INSERT INTO @TAB VALUES('TE1S', 'TE24') INSERT INTO @TAB VALUES('TE1S', 'TE25') SELECT @MAX = @@IDENTITY WHILE @COUNT <= @MAX BEGIN SELECT @COLUMN1 = COLUMN1, @COLUMN2 = COLUMN2 FROM @TAB WHERE ID = @COUNT IF @CONCAT IS NULL BEGIN SET @CONCAT = '' END ELSE BEGIN SET @CONCAT = @CONCAT + ',' END SET @CONCAT = @CONCAT + @COLUMN1 + @COLUMN2 SET @COUNT = @COUNT + 1 END SELECT @CONCAT 

मुझे लगता है कि कर्सर को एक बुरा नाम मिलता है क्योंकि एसक्यूएल के नए लोग उन्हें खोजते हैं और लगता है कि "अरे लूप के लिए हे! मुझे पता है कि उनको कैसे इस्तेमाल करना है!" और फिर वे सब कुछ के लिए उनका उपयोग करते रहेंगे

यदि आप उन्हें उन चीज़ों के लिए उपयोग करते हैं जिनके लिए वे डिज़ाइन किए गए हैं, तो मुझे उसमें गलती नहीं मिल सकती है

एसक्यूएल एक सेट आधारित भाषा है – यही वह सबसे अच्छा है।

मुझे लगता है कि कर्सर अभी भी एक बुरा विकल्प नहीं हैं, जब तक कि आप उन्हें सीमित परिस्थितियों में उनके उपयोग को सही ठहराने के बारे में पर्याप्त नहीं समझते।

एक और कारण मुझे कर्सर पसंद नहीं है स्पष्टता है कर्सर ब्लॉक इतना बदसूरत है कि यह स्पष्ट और प्रभावी तरीके से उपयोग करना मुश्किल है।

जो कुछ भी कहा गया था, ऐसे कुछ मामले हैं जहां कर्सर वास्तव में सबसे अच्छा होता है – वे आमतौर पर ऐसे मामलों में नहीं होते हैं, जो शुरुआती उन लोगों के लिए उपयोग करना चाहते हैं।

कभी-कभी प्रसंस्करण की प्रकृति की आवश्यकता आपको कर्सर की आवश्यकता होती है, हालांकि प्रदर्शन के कारणों से यदि संभव हो तो सेट-आधारित तर्क का उपयोग करके ऑपरेशन (नों) को लिखना बेहतर होता है।

मैं इसे कर्सर का उपयोग करने के लिए "बुरा व्यवहार" नहीं कहूंगा, लेकिन वे सर्वर पर अधिक संसाधनों का उपयोग करते हैं (समतुल्य सेट-आधारित दृष्टिकोण से) और ज़्यादा बार ज़रूरी नहीं होते हैं यह देखते हुए, मेरी सलाह एक कर्सर का सहारा लेने से पहले अन्य विकल्पों पर विचार करना होगा।

कई प्रकार के कर्सर हैं (केवल अग्रेषित, स्थैतिक, कीसेट, गतिशील)। प्रत्येक के पास अलग-अलग प्रदर्शन विशेषताओं और संबद्ध ओवरहेड हैं। सुनिश्चित करें कि आप अपने ऑपरेशन के लिए सही कर्सर प्रकार का उपयोग करते हैं। फॉरवर्ड केवल डिफ़ॉल्ट है

कर्सर का उपयोग करने के लिए एक तर्क तब होता है जब आपको अलग-अलग पंक्तियों को संसाधित करने और अपडेट करने की आवश्यकता होती है, विशेषकर एक डाटासेट के लिए जिसमें एक अच्छी अनूठी कुंजी नहीं होती है उस स्थिति में आप कर्सर की घोषणा करते समय UPDATE क्लॉज का उपयोग कर सकते हैं और अद्यतन अपडेट के साथ अपडेट कर सकते हैं … जहां की वर्तमान।

ध्यान दें कि "सर्वर-साइड" कर्सर लोकप्रिय (ओडीबीसी और ओएलई डीबी) से होते थे, लेकिन एडीओ। नेट उन्हें समर्थन नहीं करता, और एएएएआईएसी कभी नहीं होगा।

बहुत, बहुत कम ऐसे मामले हैं जहां कर्सर का उपयोग उचित है। लगभग कोई भी मामला नहीं है, जहां यह एक संबंधपरक, सेट-आधारित क्वेरी को मात देगा। कभी-कभी प्रोग्रामर को loops के संदर्भ में सोचना आसान होता है, लेकिन सेट लॉजिक का उपयोग, उदाहरण के लिए तालिका में बड़ी संख्या में पंक्तियों को अपडेट करने के लिए, एक समाधान होता है जो न केवल एसक्यूएल कोड की बहुत कम पंक्तियां है, लेकिन यह बहुत तेजी से चलता है, अक्सर तीव्रता के कई आदेश तेजी से

यहां तक ​​कि एसक्यूएल सर्वर 2005 में फास्ट फॉरवर्ड कर्सर सेट-आधारित प्रश्नों के साथ प्रतिस्पर्धा नहीं कर सकते। प्रदर्शन में गिरावट का आलेख अक्सर सेट-आधारित की तुलना में एन ^ 2 की तरह दिखता है, जो अधिक रैखिक होता है क्योंकि डेटा सेट बहुत बड़ा हो जाता है

@ डैनियल पी -> आपको यह करने के लिए कर्सर का उपयोग करने की आवश्यकता नहीं है। आप इसे करने के लिए आसानी से सेट आधारित सिद्धांत का उपयोग कर सकते हैं उदा: एससीएल 2008 के साथ

 DECLARE @commandname NVARCHAR(1000) = ''; SELECT @commandname += 'truncate table ' + tablename + '; '; FROM tableNames; EXEC sp_executesql @commandname; 

बस जो कुछ आपने कहा है वो करना होगा और आप एसक्यूएल 2000 के साथ ऐसा कर सकते हैं लेकिन क्वेरी की सिंटैक्स अलग-अलग होगी।

हालांकि, मेरी सलाह संभव है कि कर्सर को जितना संभव हो सके।

Gayam

कर्सर का स्थान होता है, हालांकि मुझे लगता है कि इसका मुख्य कारण है क्योंकि अक्सर इसका उपयोग किया जाता है जब एक एकल चयन कथन परिणाम को एकत्रीकरण और फ़िल्टरिंग प्रदान करने के लिए पर्याप्त होगा।

कर्सर से बचने के लिए SQL सर्वर को क्वेरी के प्रदर्शन को और अधिक पूर्णतः अनुकूलित करने की अनुमति मिलती है, जो बड़े सिस्टम में बहुत महत्वपूर्ण है।

कर्सर आमतौर पर बीमारी नहीं हैं, लेकिन इसका एक लक्षण: सेट-आधारित दृष्टिकोण का उपयोग नहीं करना (जैसा कि दूसरे उत्तर में उल्लिखित है)।

इस समस्या को समझना नहीं, और बस यह विश्वास करना है कि "बुराई" कर्सर से बचने से इसे हल होगा, चीजों को और भी बदतर बना सकता है

उदाहरण के लिए, अन्य चलने वाले कोड द्वारा कर्सर चलना की जगह, जैसे कि अस्थायी तालिकाओं या तालिका चर में डेटा को स्थानांतरित करने के लिए, पंक्तियों के ऊपर लूप पर जैसे:

 SELECT * FROM @temptable WHERE Id=@counter 

या

 SELECT TOP 1 * FROM @temptable WHERE Id>@lastId 

इस तरह के एक दृष्टिकोण, जैसा कि एक और उत्तर के कोड में दिखाया गया है, चीजें बहुत खराब बनाती हैं और मूल समस्या को ठीक नहीं करती हैं। यह एक विरोधी-पैटर्न है जिसे कार्गो पंथी प्रोग्रामिंग कहा जाता है: यह जानकर नहीं कि कुछ बुरा क्यों है और इस तरह से इसे से बचने के लिए कुछ बुराई को लागू करना! मैंने हाल ही में इस तरह के कोड को बदल दिया है (पहचानकर्ता / पीके पर एक #temptable और कोई सूचकांक का उपयोग करके) वापस कर्सर में नहीं, और 10000 से अधिक पंक्तियों को अद्यतन करने से लगभग 3 मिनट के बजाय केवल 1 सेकेंड ले लिया है। अभी भी सेट आधारित दृष्टिकोण (कम बुराई) की कमी है, लेकिन सबसे अच्छा मैं उस पल कर सकता है।

समझ की इस कमी का एक और लक्षण हो सकता है जिसे मैंने कभी-कभी "एक वस्तु रोग" कहा है: डाटाबेस अनुप्रयोग जो डेटा ऑब्जेक्ट परतों या ऑब्जेक्ट-रिलेशनल मैपर्स के माध्यम से एक ऑब्जेक्ट को संभालते हैं। आमतौर पर कोड की तरह:

 var items = new List<Item>(); foreach(int oneId in itemIds) { items.Add(dataAccess.GetItemById(oneId); } 

के बजाय

 var items = dataAccess.GetItemsByIds(itemIds); 

सबसे पहले आम तौर पर कई चुनौतियों के साथ डेटाबेस बाढ़ आएगा, प्रत्येक के लिए एक दौर की यात्रा, विशेष रूप से जब ऑब्जेक्ट पेड़ / आलेख खेलें और कुख्यात SELECT N + 1 समस्या स्ट्राइक।

यह रिलेशनल डेटाबेस और सेट आधारित दृष्टिकोण को समझने के लिए नहीं है, केवल एक ही तरीके से कर्सर तब होते हैं जब प्रक्रिया एसक्यूएल या पीएल / एसक्यूएल जैसे प्रक्रियात्मक डेटाबेस कोड का उपयोग करते हैं!

मूलभूत मुद्दे, मुझे लगता है कि डाटाबेस तैयार-आधारित संचालन के लिए डिज़ाइन और ट्यून किए गए हैं – डेटा में संबंधों के आधार पर एक त्वरित कदम में बड़ी मात्रा में डेटा का चयन, अपडेट और हटाए जाएंगे।

दूसरी ओर, इन-मेमोरी सॉफ़्टवेयर, अलग-अलग कार्यों के लिए डिज़ाइन किया गया है, इसलिए प्रत्येक डेटा पर संभवतः प्रत्येक डेटा पर अलग-अलग संचालन करने के लिए डेटा के एक सेट पर लूपिंग करना संभवतः सबसे अच्छा है

लूपिंग, डेटाबेस या स्टोरेज आर्किटेक्चर के लिए डिज़ाइन नहीं किया जाता है, और यहां तक ​​कि SQL Server 2005 में भी, आप किसी भी कस्टम प्रोग्राम में सेट किए गए मूल डेटा को खींचते हैं और मेमोरी में पाशन करते हैं , डाटा ऑब्जेक्ट्स / संरचनाओं का उपयोग करके जो संभवतया हल्के होते हैं।