CTE और SubQuery के बीच अंतर?


143

इस पोस्ट से निम्न प्रक्रिया में ROW_NUMBER का उपयोग कैसे करें?

उत्तरों के दो संस्करण हैं जहां एक का उपयोग करता है sub-queryऔर दूसरा CTEउसी समस्या को हल करने के लिए उपयोग करता है।

अब फिर, CTE (Common Table Expression)एक 'उप-क्वेरी' का उपयोग करने का क्या फायदा है (इस प्रकार, अधिक पठनीय वास्तव में क्वेरी क्या कर रहा है)

एक का उपयोग कर के केवल लाभ CTEसे अधिक sub-selectहै कि मैं वास्तव सकता है नामsub-query । क्या उन दो के बीच कोई अन्य अंतर है जब एक सीटीई एक सरल (गैर-पुनरावर्ती) सीटीई के रूप में उपयोग किया जाता है?


अच्छी चर्चा के साथ व्युत्पन्न प्रश्न: stackoverflow.com/q/11169550/781695
उपयोगकर्ता 10

7
IMO, जो कोई भी CTE के बारे में सोचता है, वह कम पठनीय होता है कि इंटरवेवन सबक्वेरीज़ की विशालकाय बूँद ने एंटरप्राइज़ डेटा प्रबंधन प्रणालियों के अधिकांश हिस्से में उपयोग किए गए आरा-टूथ-आकार के प्रश्नों को भ्रमित करने का कचरा ढेर नहीं देखा है। बड़ी, गैर-तुच्छ क्वेरी आमतौर पर नाटकीय रूप से बाद में या उप-विषयों की तुलना में नई आँखों से पढ़ना आसान है, और कम से कम पोस्टग्रैज के मामले में जादुई रूप से कई मामलों में बहुत बेहतर प्रदर्शन करते हैं। ([कारणों से मुझे अभी तक समझना है [( stackoverflow.com/questions/33731068/… ), जैसा कि इसके विपरीत होने की अधिक संभावना है।)
zxq9

जवाबों:


102

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

में सामान्य ; एक सीटीई का पुनरावर्ती उपयोग किया जा सकता है; एक उप-क्वेरी नहीं कर सकते। यह उन्हें पेड़ संरचनाओं के लिए विशेष रूप से अच्छी तरह से अनुकूल बनाता है।


1
क्षमा करें, मुझे अपने प्रश्न में अधिक स्पष्ट होना चाहिए था। उस संदर्भ में CTE और Subquery के बीच अंतर क्या होगा जहां CTE का उपयोग LIKE सबक्वेरी में किया जाता है?
डांस

2
@ मारक ग्रेवेल: हम इससे अधिक कर सकते हैं, क्योंकि प्रोफाइलर के व्यवहार की गारंटी नहीं है, बनाम सीटीई का व्यवहार, जो कि (मूल्यांकन के संदर्भ में) है।
कैस्पर ओने

1
यह सुनिश्चित नहीं है कि सीटीएस और उप-अंतर अंतर को देखने वाले लोगों के लिए यह कथन कितना मायने रखता है - A CTE can be used recursively; a sub-query cannot। एक उदाहरण बहुत अच्छा रहा होगा।
अनिकेत ठाकुर

88

कॉमन टेबल एक्सप्रेशन ( पुनरावर्ती प्रश्नों के लिए इसका उपयोग नहीं करने पर ) का मुख्य लाभ एनकैप्सुलेशन है, इसके बजाय कि आप इसे उपयोग करने की इच्छा रखने वाले प्रत्येक स्थान पर उप-क्वेरी घोषित करने के बजाय, आप इसे एक बार परिभाषित करने में सक्षम हैं, लेकिन कई संदर्भ हैं यह करने के लिए।

हालांकि, इसका मतलब यह नहीं है कि यह केवल एक बार निष्पादित किया जाता है ( इस बहुत ही उत्तर के पिछले पुनरावृत्तियों के अनुसार , उन सभी को धन्यवाद जो टिप्पणी की है)। यदि निश्चित रूप से कई बार संदर्भित होने पर क्वेरी को निश्चित रूप से कई बार निष्पादित किया जा सकता है; क्वेरी ऑप्टिमाइज़र अंततः निर्णय लेता है कि CTE की व्याख्या कैसे की जानी चाहिए।


"एक सीटीई को एक अस्थायी तालिका चर के रूप में सोचो" इसका मतलब है कि सीटीई डिस्क या मेमोरी में संग्रहीत है?
डांस

आप परिभाषा द्वारा CTE या सबक्वेरी का उपयोग कई प्रश्नों में नहीं कर सकते हैं। मुझे पूरा यकीन है कि ऑप्टिमाइज़र उपनगर को उसी तरह से संभालता है जिस तरह से यह सीटीई (केवल एक बार सेट किए गए परिणाम का मूल्यांकन करता है, चाहे वह 1 क्वेरी के भीतर कितनी बार उपयोग किया गया हो) को
संभाल लेगा

@AlexCuse: मुझे लगता है कि मैंने सीटीई के संदर्भ को पर्याप्त रूप से स्पष्ट कर दिया है, लेकिन मैंने कोशिश करने और अधिक स्पष्ट करने के लिए और अधिक जोड़ा।
कैस्पर ओने

@AlexCuse: इसका कोई निहितार्थ नहीं है कि CTE या उपकुंजी का उपयोग कई स्थानों पर किया जा सकता है। CTE और ऑप्टिमाइज़र के बीच अंतर हालांकि यह है कि CTE के व्यवहार की गारंटी है, जबकि अनुकूलक का व्यवहार नहीं है।
कैस्पर ओने

और मैं यह स्वीकार करूंगा कि कुछ किनारे मामले हो सकते हैं जहां ऑप्टिमाइज़र चोक हो जाता है और सबक्वेरी का मूल्यांकन एक से अधिक बार किया जाता है, लेकिन मैं किसी भी तरह से नहीं चला हूं। फिर दोबारा, मैं सीटीई का उपयोग जहां भी कर सकता हूं;)
एलेक्सक्यूस

15

CTEपुनरावृत्ति के लिए सबसे उपयोगी हैं:

WITH hier(cnt) AS (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt < @n
        )
SELECT  cnt
FROM    hier

@nपंक्तियों को वापस करेगा (अप करने के लिए 101)। कैलेंडर, डमी पंक्तियों आदि के लिए उपयोगी है।

वे अधिक पठनीय भी हैं (मेरी राय में)।

इसके अलावा, समान हैं CTEऔर subqueriesसमान हैं।


MSSQL में, आपको एक अर्धविराम (;) जोड़ने की आवश्यकता है, इससे पहले कि आप वार करें, आपको एक त्रुटि मिलेगी। यह होना चाहिए;WITH blabla AS ...)
Obinna Nnenanya

2
@ObinnaNnenanya: केवल अगर यह बैच में पहला बयान नहीं है। अर्धविराम के साथ अपने बयानों को समाप्त करना वैसे भी एक अच्छा विचार है, भले ही SQL सर्वर वर्तमान संस्करणों में इसे पहले के अलावा लागू नहीं करता है WITH, MERGEऔर इसी तरह
Quassnoi

10

एक अंतर जिसका उल्लेख नहीं किया गया है वह एक एकल सीटीई है जिसे संघ के कई हिस्सों में संदर्भित किया जा सकता है


8

जब तक मैं कुछ याद नहीं कर रहा हूँ, आप आसानी से CTE और सबक्वेरीज़ को नाम दे सकते हैं।

मुझे लगता है कि मुख्य अंतर पठनीयता है (मुझे सीटीई अधिक पठनीय लगता है क्योंकि यह आपके उपसमुच्चय को मध्य की बजाय सामने की ओर परिभाषित करता है)।

और यदि आपको पुनरावृत्ति के साथ कुछ भी करने की आवश्यकता है, तो आपको उपश्रम के साथ ऐसा करने में थोड़ी परेशानी होगी;)


1
मुझे यकीन नहीं है कि कोई गैर-सौंदर्य अंतर है (हालांकि मुझे उम्मीद है कि कुछ स्थितियों में निष्पादन योजना में मामूली अंतर हो सकता है)। मेरी देखभाल करने के लिए?
एलेक्सक्यूज

2
आप सीटीई का नाम दे सकते हैं, लेकिन आप केवल उर्फ उपश्रेणियों को देख सकते हैं । अंतर यह है कि, आप कई उपनामों के साथ सीटीई का पुन: उपयोग कर सकते हैं (cf. @Michael Petito का उदाहरण कैस्परऑन के लिए अपनी टिप्पणी में)। मैं किसी भी तरह से नहीं जानता कि उपश्रेणियों के साथ।
किमी

7

एक महत्वपूर्ण तथ्य जो किसी ने उल्लेख नहीं किया है, वह है (कम से कम पोस्टग्रेज में), सीटीई ऑप्टिमाइज़ेशन बाड़ हैं:

https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/

यही है, उन्हें पूरे क्वेरी प्लान में तह करने के बजाय उनकी खुद की परमाणु क्वेरी के रूप में माना जाएगा। मेरे पास बेहतर स्पष्टीकरण देने के लिए विशेषज्ञता की कमी है, लेकिन आपको अपने द्वारा उपयोग किए जा रहे एसक्यूएल के संस्करण के लिए शब्दार्थ की जांच करनी चाहिए; उन्नत उपयोगकर्ताओं के लिए, एक अनुकूलन बाड़ बनाने में सक्षम होने से प्रदर्शन को मदद मिल सकती है यदि आप क्वेरी प्लानर को नियंत्रित करने में विशेषज्ञ स्तर हैं; 99% मामलों में, हालांकि, आपको क्वेरी प्लानर को यह बताने की कोशिश करने से बचना चाहिए कि क्या करना है, क्योंकि आपको लगता है कि यह तेजी से होने की संभावना से भी बदतर है। :-)


6

दूसरों के उत्तरों को जोड़ना, यदि आपके पास एक और एक ही सबक्वेरी का उपयोग कई बार किया जाता है, तो आप इन सभी उप-श्रेणियों को एक सीटीई के साथ बदल सकते हैं। इससे आप अपने कोड का बेहतर उपयोग कर सकते हैं।


4

एक बात जो आपको समझने की ज़रूरत है वह यह है कि SQL सर्वर के पुराने संस्करणों में (हाँ कई लोगों को अभी भी SQL Server 2000 डेटाबेस का समर्थन करने की आवश्यकता है), CTE को अनुमति नहीं है और फिर व्युत्पन्न तालिका आपका सबसे अच्छा समाधान है।


2

सुझाव: (MAXRECURSION n)

आप का उपयोग करके प्रत्यावर्तन का स्तर एक विशिष्ट बयान के लिए अनुमति दी की संख्या को सीमित कर सकते हैं MAXRECURSIONसंकेत और के बीच कोई मान 0 और 32,767 में OPTIONखंड

उदाहरण के लिए, आप कोशिश कर सकते हैं:

OPTION 
      (MAXRECURSION 150)

GO
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.