कार्यों बनाम संग्रहीत कार्यविधियाँ


88

मान लीजिए कि मुझे T-SQL कोड का एक टुकड़ा लागू करना है जो परिणाम के रूप में एक तालिका वापस करना होगा। मैं एक टेबल-वैल्यू फ़ंक्शन को लागू कर सकता हूं या एक संग्रहीत प्रक्रिया को लागू कर सकता हूं जो पंक्तियों का एक सेट लौटाता है। मुझे क्या उपयोग करना चाहिए?

संक्षेप में, जो मैं जानना चाहता हूं वह है:

फ़ंक्शंस और संग्रहीत प्रक्रियाओं के बीच मुख्य अंतर क्या हैं? एक या दूसरे का उपयोग करने के लिए मुझे क्या विचार करना होगा?


1
यह सही उत्तर प्रतीत होता है: stackoverflow.com/a/1179778/365188
ओजैर कफ़्रे

जवाबों:


51

यदि आप कोड के इस टुकड़े के परिणाम को अन्य तालिकाओं के साथ संयोजित करना चाहते हैं, तो जाहिर है कि तालिका-मूल्यवान फ़ंक्शन आपको एकल चयन कथन में परिणाम लिखने की अनुमति देगा।

आम तौर पर, एक पदानुक्रम होता है (देखें <टीवी समारोह <संग्रहीत प्रोसी)। आप हर एक में अधिक कर सकते हैं, लेकिन आउटपुट को कंपोज करने की क्षमता और ऑप्टिमाइज़र को वास्तव में शामिल करने के लिए कार्यक्षमता बढ़ने के साथ घट जाती है।

इसलिए जो भी एक न्यूनतम उपयोग करें, वह आपको अपना वांछित परिणाम व्यक्त करने की अनुमति देता है।


50

फ़ंक्शंस नियतात्मक होना चाहिए, और इसका उपयोग डेटाबेस में परिवर्तन करने के लिए नहीं किया जा सकता है, जबकि संग्रहीत कार्यविधियाँ आपको आवेषण और अद्यतन आदि करने की अनुमति देती हैं।

आपको अपने कार्यों के उपयोग को सीमित करना चाहिए, क्योंकि वे बड़े, जटिल प्रश्नों के लिए एक बड़ी मापनीयता की समस्या पैदा करते हैं। वे क्वेरी ऑप्टिमाइज़र के लिए "ब्लैक बॉक्स" की तरह बन जाते हैं, और आप फ़ंक्शंस का उपयोग करने और कोड को क्वेरी में डालने के बीच प्रदर्शन में भारी अंतर देखेंगे।

लेकिन वे निश्चित रूप से बहुत विशिष्ट मामलों में तालिका-मूल्यवान रिटर्न के लिए उपयोगी हैं।

यदि आपको एक अल्पविराम-सीमांकित सूची को पार्स करने की आवश्यकता है, तो एक सरणी को एक प्रक्रिया में अनुकरण करने के लिए, एक फ़ंक्शन सूची को आपके लिए तालिका में बदल सकता है। Sql Server 2005 के साथ यह आम बात है, क्योंकि हम तालिकाओं को अभी तक संग्रहीत प्रक्रियाओं में पारित नहीं कर सकते हैं (हम 2008 के साथ कर सकते हैं)।


1
लेकिन आप XML को एक संग्रहित प्रक्रिया में भेज सकते हैं: stackoverflow.com/questions/144550/…
cllpse

2
गलत, अधिकांश SQL सर्वर फ़ंक्शन गैर-निर्धारक होते हैं, जैसे MS-SQL सर्वर में गेटडेट। केवल ODBC फ़ंक्शंस कैनोनिकल फ़ंक्शंस (= बहुत तेज़ + इंडेक्सेबल) हैं ... लेकिन आप बहुत सही हैं, व्यक्ति को प्रदर्शन कारणों से यथासंभव प्रश्नों में फ़ंक्शंस के उपयोग को सीमित करना चाहिए।
स्टीफन स्टीगर

45

डॉक्स से :

यदि एक संग्रहीत प्रक्रिया निम्नलिखित मानदंडों को पूरा करती है, तो यह एक टेबल-वैल्यू फ़ंक्शन के रूप में फिर से लिखे जाने के लिए एक अच्छा उम्मीदवार है:

  • तर्क एकल चयन कथन में अभिव्यक्त होता है, लेकिन एक संग्रहीत प्रक्रिया है, केवल दृश्य के बजाय, मापदंडों की आवश्यकता के कारण।

  • संग्रहीत कार्यविधि तालिका चर को छोड़कर अद्यतन कार्रवाई नहीं करती है।

  • गतिशील EXECUTE कथनों की कोई आवश्यकता नहीं है।

  • संग्रहीत कार्यविधि एक परिणाम सेट देता है।

  • संग्रहीत प्रक्रिया का प्राथमिक उद्देश्य मध्यवर्ती परिणामों का निर्माण करना है जिन्हें एक अस्थायी तालिका में लोड किया जाना है, जिसे तब एक SELECT कथन में क्वेर किया गया है।


12

मैं संग्रहीत प्रक्रियाओं और कार्यों के बीच कुछ दिलचस्प अंतर लिखने जा रहा हूं।

  • हम चुनिंदा क्वेरीज़ में फ़ंक्शन का उपयोग कर सकते हैं लेकिन हम चुनिंदा क्वेरीज़ में संग्रहीत कार्यविधियों का उपयोग नहीं कर सकते।
  • हम कार्यों में गैर नियतात्मक कार्यों का उपयोग नहीं कर सकते हैं लेकिन हम संग्रहीत प्रक्रियाओं में गैर नियतात्मक कार्यों का उपयोग कर सकते हैं। अब सवाल उठता है कि गैर नियतात्मक कार्य क्या है .. उत्तर है: -

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

    अपवाद: -

    SQL 2000 से पहले sql सर्वर के पुराने संस्करण उपयोगकर्ता परिभाषित कार्यों में getdate () फ़ंक्शन का उपयोग करने की अनुमति नहीं देते हैं, लेकिन संस्करण 2005 और उसके बाद हमें उपयोगकर्ता परिभाषित फ़ंक्शन के भीतर getdate () फ़ंक्शन का उपयोग करने की अनुमति देता है।

    न्यूड () गैर-नियतात्मक फ़ंक्शन का एक और उदाहरण है, लेकिन इसका उपयोग उपयोगकर्ता परिभाषित कार्यों में नहीं किया जा सकता है लेकिन हम इसे संग्रहीत कार्यविधि में उपयोग कर सकते हैं।

  • हम एक संग्रहीत कार्यविधि के भीतर डीएमएल (इन्सर्ट, अपडेट, डिलीट) स्टेटमेंट का उपयोग कर सकते हैं, लेकिन हम डीएमएल स्टेटमेंट को फिजिकल टेबल या स्थायी टेबल पर काम नहीं कर सकते। यदि हम कार्यों में डीएमएल ऑपरेशन करना चाहते हैं तो हम इसे टेबल वेरिएबल पर कर सकते हैं न कि स्थायी टेबल पर।

  • हम फ़ंक्शन के भीतर त्रुटि हैंडलिंग का उपयोग नहीं कर सकते हैं, लेकिन हम संग्रहीत प्रक्रियाओं में त्रुटि हैंडलिंग कर सकते हैं।


MySQL फ़ंक्शंस में डीएमएल संचालन का समर्थन कैसे किया जाता है?
जॉय पिंटो

@JoeyPinto। क्योंकि myNONsql SQL शिकायत नहीं है। निश्चित रूप से, इसमें एक्स्ट्रा है, लेकिन मूल बातें नहीं।
प्रदर्शन

8
  1. प्रक्रिया शून्य या एन मान वापस कर सकती है जबकि फ़ंक्शन एक मान वापस कर सकता है जो अनिवार्य है।

  2. प्रक्रियाओं में इसके लिए इनपुट / आउटपुट पैरामीटर हो सकते हैं जबकि फ़ंक्शंस में केवल इनपुट पैरामीटर हो सकते हैं।

  3. कार्यविधि चयन के साथ-साथ डीएमएल कथन में भी अनुमति देता है, जबकि फ़ंक्शन केवल इसमें कथन का चयन करने की अनुमति देता है।

  4. कार्यविधियों को प्रक्रिया से बुलाया जा सकता है, जबकि प्रक्रियाओं को कार्य से नहीं बुलाया जा सकता है।

  5. अपवाद को एक प्रक्रिया में कोशिश-कैच ब्लॉक द्वारा नियंत्रित किया जा सकता है, जबकि कोशिश-पकड़ ब्लॉक का उपयोग किसी फ़ंक्शन में नहीं किया जा सकता है।

  6. हम प्रक्रिया में लेनदेन प्रबंधन के लिए जा सकते हैं, जबकि हम फ़ंक्शन में नहीं जा सकते।

  7. कार्यविधियों का चयन किसी कथन में नहीं किया जा सकता है जबकि कार्य का चयन किसी कथन में किया जा सकता है।

  8. UDF (यूजर डिफाइंड फंक्शन) का उपयोग SQL स्टेटमेंट में कहीं भी WHERE/ HAVING/ SELECTसेक्शन में किया जा सकता है, जबकि संग्रहीत कार्यविधियाँ नहीं हो सकती हैं।

  9. यूडीएफ जो कि टेबल लौटाते हैं, उन्हें दूसरी पंक्तियों के रूप में माना जा सकता है। इसका उपयोग JOINअन्य तालिकाओं के साथ किया जा सकता है ।

  10. इनलाइन UDFs, हालांकि उन विचारों के रूप में हो सकते हैं जो पैरामीटर लेते हैं और JOINएस और अन्य रोसेट ऑपरेशन में उपयोग किए जा सकते हैं ।


6

यदि आपके पास एक फ़ंक्शन है, तो आप इसे अपने SQL कथन के भाग के रूप में उपयोग कर सकते हैं, उदाहरण के लिए

SELECT function_name(field1) FROM table

यह संग्रहीत कार्यविधियों के लिए इस तरह से काम नहीं करता है।


1
मुझे लगता है कि वह उन कार्यों के बारे में बात कर रहा था जो तालिका मूल्यों को वापस करते हैं।
12

1
खैर, मैं सामान्य रूप से बात कर रहा हूं। लेकिन मेरे विशिष्ट मामले के लिए मैं अब एक संग्रहीत प्रक्रिया या तालिका-मूल्यवान फ़ंक्शन के बीच हूं।
अरोन

5

मैंने कुछ परीक्षणों को एक लंबे समय तक चलने वाले तर्क के साथ चलाया, जिसमें एक ही बिट कोड (एक लंबा चयन कथन) के साथ एक टेबल वैल्यूड फंक्शन और एक संग्रहीत प्रक्रिया, और एक सीधे EXEC / SELECT दोनों चल रहे थे, और प्रत्येक ने पहचान की।

मेरे विचार में, परिणाम सेट करने के लिए संग्रहीत प्रक्रिया के बजाय हमेशा टेबल वेल्यूएड फ़ंक्शन का उपयोग करें, क्योंकि यह लॉजिक को प्रश्नों में बहुत आसान और पठनीय बनाता है जो बाद में उनके साथ जुड़ जाता है, और आपको उसी तर्क का पुन: उपयोग करने में सक्षम बनाता है। प्रदर्शन के बहुत अधिक हिट से बचने के लिए, मैं अक्सर "वैकल्पिक" मापदंडों का उपयोग करता हूं (यानी आप उन्हें NULL पास कर सकते हैं) फ़ंक्शन को सक्षम करने के लिए परिणाम सेट करने के लिए जल्दी, जैसे:

CREATE FUNCTION dbo.getSitePermissions(@RegionID int, @optPersonID int, optSiteID int)
AS
RETURN 
    SELECT DISTINCT SiteID, PersonID
    FROM dbo.SiteViewPermissions
    WHERE (@optPersonID IS NULL OR @optPersonID = PersonID)
    AND (@optSiteID IS NULL OR @optSiteID = SiteID)
    AND @RegionID = RegionID

इस तरह आप कई अलग-अलग स्थितियों के लिए इस फ़ंक्शन का उपयोग कर सकते हैं, और एक बड़ा प्रदर्शन हिट नहीं कर सकते। मेरा मानना ​​है कि यह बाद में छानने की तुलना में अधिक कुशल है:

SELECT * FROM dbo.getSitePermissions(@RegionID) WHERE SiteID = 1

मैंने इस तकनीक का उपयोग कई कार्यों में किया है, कभी-कभी इस प्रकार के "वैकल्पिक" मापदंडों की लंबी सूची के साथ।


4

जब मैं वापस आ रहा हूं तो मैं व्यक्तिगत रूप से टेबल वैल्यूड फंक्शन्स का उपयोग करता हूं। मूल रूप से मैं उन्हें मापदंडों के विचारों की तरह मानता हूं।

अगर मुझे लौटे कई रिकॉर्डसेट की आवश्यकता है या यदि टेबल्स में अपडेट किए गए मान होंगे, तो मैं एक संग्रहीत प्रक्रिया का उपयोग करता हूं।

मेरे 2 सेंट


4

जैसा कि ऊपर उल्लेख किया गया है, फ़ंक्शंस अधिक पठनीय / रचना / स्व-दस्तावेजीकरण हैं, लेकिन सामान्य रूप से कम प्रदर्शन करने वाले हैं, और यदि आप उनके साथ जुड़ जाते हैं, तो आप कम गंभीरता से प्रदर्शन कर सकते हैं जैसे कि

SELECT *
FROM dbo.tvfVeryLargeResultset1(@myVar1) tvf1
INNER JOIN dbo.tvfVeryLargeResultset1(@myVar2) tvf2
    ON (tvf1.JoinId = tvf2.JoinId)

अक्सर, आपको बस कोड की अतिरेक को स्वीकार करना होगा जिसे एक टीवीएफ समाप्त कर सकता है (अस्वीकार्य प्रदर्शन लागत पर।)

एक अन्य बिंदु जिसका मैंने अभी तक उल्लेख नहीं किया है, वह यह है कि आप मल्टी-स्टेटमेंट टीवीएफ के अंदर डेटाबेस स्टेट-टेंपिंग टेबल का उपयोग नहीं कर सकते। एक अस्थायी तालिका के लिए सबसे कार्यात्मक रूप से समतुल्य तंत्र मेमोरी टेबल चर में गैर-राज्य परिवर्तन है, और बड़े डेटासेट के लिए, एक अस्थायी तालिका संभवतः तालिका चर की तुलना में अधिक प्रदर्शनशील होगी। (अन्य विकल्पों में डायनेमिक टेबल और कॉमन टेबल वैल्यू एक्सप्रेशन शामिल हैं, लेकिन जटिलता के कुछ स्तर पर, ये एक अच्छा विकल्प OO बनने के लिए बंद हो जाते हैं।)


1

मैं दोनों को टेस्ट करूंगा। यह संभावना है कि सपा दृष्टिकोण या एक व्युत्पन्न तालिका एक फ़ंक्शन की तुलना में काफी तेज होगी और यदि ऐसा है तो दृष्टिकोण का उपयोग किया जाना चाहिए। सामान्य तौर पर मैं फ़ंक्शन से बचता हूं क्योंकि वे प्रदर्शन हॉग हो सकते हैं।


1

यह निर्भर करता है :) यदि आप किसी अन्य प्रक्रिया में तालिका-मूल्यवान परिणाम का उपयोग करना चाहते हैं, तो आप TableValued फ़ंक्शन का उपयोग करने के लिए बेहतर हैं। यदि परिणाम एक ग्राहक के लिए है, तो संग्रहीत खरीद सामान्य रूप से जाने का बेहतर तरीका है।


-1

संग्रहीत प्रक्रियाएं पूर्व संकलित क्वेरी हैं जो तेजी से निष्पादित होती हैं और एसक्यूएल इंजेक्शन से बचाती हैं। वे 0 या N मान वापस कर सकते हैं। हम संग्रहीत प्रक्रियाओं के अंदर डीएमएल संचालन कर सकते हैं। हम प्रक्रियाओं के अंदर फ़ंक्शन का उपयोग कर सकते हैं और चुनिंदा क्वेरी में फ़ंक्शन का उपयोग कर सकते हैं। कार्यों में किसी भी मूल्य और डीएमएल संचालन को संभव नहीं करने के लिए फ़ंक्शंस का उपयोग किया जाता है। फ़ंक्शंस दो प्रकार के होते हैं स्केलर और टैब्लेट-वैल्यू। स्केलर फ़ंक्शन एक एकल मान लौटाता है, टेबल की पंक्तियों को लौटाने के लिए उपयोग किया जाने वाला tabled-मूल्यवान फ़ंक्शन।


यह एक बहुत पुराना प्रश्न है जिसमें बड़ी संख्या में उत्तर हैं, उनमें से कई (स्वीकृत उत्तर सहित) अत्यधिक उत्कीर्ण हैं। इस तरह के धागे के लिए एक और उत्तर जोड़ने से पहले, आपको खुद से पूछना चाहिए, "उन सभी मौजूदा उत्तरों में क्या कमी है जो मुझे एक दूसरे को लिखने की आवश्यकता है?"
एपीसी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.