CTE और Temp Table में क्या अंतर है?


174

कॉमन टेबल एक्सप्रेशन (CTE) और टेम्प टेबल के बीच क्या अंतर है? और मुझे कब एक का उपयोग करना चाहिए?

CTE

WITH cte (Column1, Column2, Column3)
AS
(
    SELECT Column1, Column2, Column3
    FROM SomeTable
)

SELECT * FROM cte

अस्थायी तालिका

SELECT Column1, Column2, Column3
INTO #tmpTable
FROM SomeTable

SELECT * FROM #tmpTable


जवाबों:


200

यह बहुत व्यापक है, लेकिन मैं आपको सामान्य उत्तर के रूप में दे सकता हूं।

सीटीई ...

  • अनियंत्रित हैं (लेकिन संदर्भित वस्तुओं पर मौजूदा अनुक्रमित का उपयोग कर सकते हैं)
  • अड़चन नहीं हो सकती
  • अनिवार्य रूप से डिस्पोजेबल VIEWएस
  • केवल तब तक जारी रखें जब तक कि अगली क्वेरी न चला दी जाए
  • पुनरावर्ती हो सकता है
  • समर्पित आँकड़े नहीं हैं (अंतर्निहित वस्तुओं पर आँकड़ों पर भरोसा करें)

# टेबल्स टेबल्स ...

  • वास्तविक भौतिक तालिकाओं हैं जो टेम्पर्ड में मौजूद हैं
  • अनुक्रमित किया जा सकता है
  • अड़चन हो सकती है
  • वर्तमान संबंध के जीवन के लिए दृढ़ रहें
  • अन्य प्रश्नों या उपप्रकारों द्वारा संदर्भित किया जा सकता है
  • इंजन द्वारा उत्पन्न आँकड़े समर्पित करें

जहां तक ​​प्रत्येक का उपयोग करने के लिए, उनके पास बहुत अलग उपयोग के मामले हैं। यदि आपके पास एक बहुत बड़ा परिणाम सेट होगा, या इसे एक से अधिक बार संदर्भित करने की आवश्यकता है, तो इसे एक #tempतालिका में रखें। यदि इसे पुनरावर्ती होने की आवश्यकता है, तो डिस्पोजेबल है, या बस तार्किक रूप से कुछ को सरल बनाने के लिए है, एक CTEपसंदीदा है।

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


CTE का उपयोग करके एक बड़े MERGE को गति देना एक चीज है
AgentFire

1
CTE's का उपयोग करके कई प्रश्नों को गति देना भी एक बात है क्योंकि CTE के साथ आप क्वेरी लिंकेज सलाहकार को बेहतर बनाने के लिए अपना खुद का व्यवसाय ज्ञान जोड़ सकते हैं। उदाहरण के लिए, आप अपने CTE का भाग 1 उन तालिकाओं से चुन सकते हैं जहाँ आप जानते हैं कि परिणामी पंक्तियाँ बहुत छोटी होंगी। उसी क्वेरी के अंदर, आप इस छोटे परिणाम को कुछ बड़े परिणाम में शामिल कर सकते हैं और पूरी तरह से बासी आँकड़ों के कारण होने वाले मुद्दों को बायपास कर सकते हैं। ऐसा करने के लिए, आपको आदेश को लागू करने के लिए क्वेरी संकेत जोड़ने की आवश्यकता है। यह काम करता है, यह प्रदर्शन में सुधार करता है।
डेव हिल्डिच

"प्रदर्शन के लिए कभी भी उपयोग नहीं किया जाता है" एक व्यापक और कुछ हद तक व्यक्तिपरक कथन है, हालांकि मैं आपकी बात समझता हूं। यद्यपि, अन्य टिप्पणियों के अलावा, CTE का उपयोग करने से एक और संभावित प्रदर्शन लाभ तब हो सकता है जब पुनरावर्ती CTE को पुनरावर्ती प्रक्रिया कॉल या कर्सर जैसे किसी अन्य रूप से पुनरावर्ती CTE पर स्विच किया जा सकता है।
जद

29

संपादित करें:

कृपया मार्टिन की टिप्पणियों को नीचे देखें:

CTE को मेमोरी में टेबल के रूप में नहीं रखा जाता है। यह एक क्वेरी परिभाषा को एनकैप्सुलेट करने का एक तरीका है। ओपी के मामले में यह इनबिल्ट होगा और जैसा कर रहा है वैसा ही होगा SELECT Column1, Column2, Column3 FROM SomeTable। ज्यादातर समय वे भौतिक रूप से सामने नहीं आते हैं, यही कारण है कि यह कोई पंक्तियाँ नहीं देता है WITH T(X) AS (SELECT NEWID())SELECT * FROM T T1 JOIN T T2 ON T1.X=T2.X, निष्पादन योजनाओं की भी जांच करें। हालांकि कभी-कभी स्पूल प्राप्त करने के लिए योजना को हैक करना संभव है। इसके लिए संकेत देने के लिए एक कनेक्ट आइटम अनुरोध है। - मार्टिन स्मिथ 15 फरवरी 12 '17:08 पर


मूल उत्तर

CTE

MSDN पर अधिक पढ़ें

CTE स्मृति में उपयोग की जा रही तालिका बनाता है, लेकिन इसके बाद विशिष्ट क्वेरी के लिए केवल मान्य है। पुनरावर्तन का उपयोग करते समय, यह एक प्रभावी संरचना हो सकती है।

आप तालिका चर का उपयोग करने पर भी विचार कर सकते हैं। यह प्रयोग किया जाता है के रूप में एक अस्थायी तालिका प्रयोग किया जाता है और इसमें शामिल होने के लिए प्रत्येक के लिए फिर से materialized किए जाने की जरूरत के बिना कई बार इस्तेमाल किया जा सकता है। इसके अलावा, अगर आपको अभी कुछ रिकॉर्ड बनाए रखने की आवश्यकता है, तो अगले चयन के बाद कुछ और रिकॉर्ड जोड़ें, एक और ऑप के बाद कुछ और रिकॉर्ड जोड़ें, फिर बस उन मुट्ठी भर रिकॉर्ड को वापस करें, फिर यह एक आसान संरचना हो सकती है, जैसा कि यह नहीं है 'निष्पादन के बाद छोड़ने की जरूरत नहीं है। ज्यादातर सिर्फ सिंटैक्टिक शुगर। हालाँकि, यदि आप पंक्ति-गणना को कम रखते हैं, तो यह कभी भी डिस्क पर नहीं जाती है। देखें कि SQL सर्वर में अस्थायी तालिका और तालिका चर के बीच अंतर क्या है? अधिक जानकारी के लिए।

अस्थायी तालिका

MSDN पर और पढ़ें - लगभग 40% तरीके से नीचे स्क्रॉल करें

एक अस्थायी तालिका वस्तुतः डिस्क पर बनाई गई एक तालिका है, बस एक विशिष्ट डेटाबेस में जिसे हर कोई जानता है हटा दिया जा सकता है। यह उन टेबल को नष्ट करने के लिए एक अच्छे देव की जिम्मेदारी है जब उन्हें अब जरूरत नहीं है, लेकिन एक डीबीए भी उन्हें मिटा सकता है।

अस्थायी तालिकाएँ दो प्रकार में आती हैं: स्थानीय और वैश्विक। एमएस Sql सर्वर के संदर्भ में आप #tableNameस्थानीय के लिए एक पदनाम का उपयोग करते हैं , और ##tableNameवैश्विक के लिए पदनाम (पहचान की विशेषता के रूप में एकल या डबल # के उपयोग पर ध्यान दें)।

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


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


11
CTE को मेमोरी में टेबल के रूप में नहीं रखा जाता है। यह एक क्वेरी परिभाषा को एनकैप्सुलेट करने का एक तरीका है। ओपी के मामले में यह इनबिल्ट होगा और ऐसा ही होगाSELECT Column1, Column2, Column3 FROM SomeTable
मार्टिन स्मिथ

4
ज्यादातर समय वे भौतिक रूप से सामने नहीं आते हैं, यही कारण है कि यह कोई पंक्तियाँ नहीं देता है WITH T(X) AS (SELECT NEWID())SELECT * FROM T T1 JOIN T T2 ON T1.X=T2.X, निष्पादन योजनाओं की भी जांच करें। हालांकि कभी-कभी स्पूल प्राप्त करने के लिए योजना को हैक करना संभव है । इसके लिए संकेत देने के लिए एक कनेक्ट आइटम अनुरोध है।
मार्टिन स्मिथ

16

यहां स्वीकार किए गए उत्तर में कहा गया है कि "प्रदर्शन के लिए सीटीई का उपयोग कभी नहीं किया जाना चाहिए" - लेकिन यह गुमराह कर सकता है। CTEs बनाम टेम्प टेबल के संदर्भ में, मैंने अभी हाल ही में संग्रहीत procs के एक सूट से कबाड़ का एक स्वैथ निकालना समाप्त किया है क्योंकि कुछ डूफस ने सोचा होगा कि अस्थायी टेबल का उपयोग करने के लिए बहुत कम या कोई ओवरहेड था। मैंने CTE में बहुत बदलाव किए, सिवाय उन लोगों के जो पूरी प्रक्रिया में फिर से इस्तेमाल होने वाले थे। मैंने सभी मेट्रिक्स द्वारा लगभग 20% प्रदर्शन प्राप्त किया। मैंने फिर उन सभी अभिशापों को दूर करने के बारे में निर्धारित किया जो पुनरावर्ती प्रसंस्करण को लागू करने की कोशिश कर रहे थे। यहीं पर मुझे सबसे ज्यादा फायदा हुआ। मैंने दस के एक कारक द्वारा प्रतिक्रिया समय को समाप्त कर दिया।

सीटीई और टेम्प टेबल में बहुत अलग उपयोग मामले हैं। मैं सिर्फ इस बात पर जोर देना चाहता हूं कि रामबाण नहीं है, सीटीई की समझ और सही उपयोग से कोड की गुणवत्ता / स्थिरता और गति दोनों में कुछ हद तक सुधार हो सकता है। जब से मुझे उन पर एक हैंडल मिला है, मैं अस्थायी तालिकाओं और कर्सर को SQL प्रसंस्करण की महान बुराइयों के रूप में देखता हूं। मैं अब लगभग हर चीज के लिए टेबल चर और सीटीई के साथ ठीक कर सकता हूं। मेरा कोड क्लीनर और तेज है।


अब, हम निष्पक्ष रहें - शाप देने वाले महान दुष्ट हैं; अस्थायी तालिकाओं में सबसे कम बुराई है। :-) जैसा कि आपने खुद देखा, उन्हें उसी स्तर पर रखना वास्तव में अनुचित है।
RDFozz

@RDFozz सही, नरक में 9 मंडलियां हैं जैसा कि हम सभी जानते हैं । चलो 2 पर अस्थायी तालिकाओं और पर कर्सर ... 7 वीं? ;)
ypercubeᵀᴹ

1
आप जानते हैं कि प्रोग्रामिंग में 'बड़ी बुराई' क्या है? जब लोग कहते हैं कि एक विशेष तकनीक बुराई है। शाप देने वालों के लिए जगह है। वे कुछ निश्चित परिदृश्यों में अन्य तकनीकों को बेहतर बना सकते हैं। यहां कोई बुराई नहीं है - आपको नौकरी के लिए सही उपकरण का उपयोग करना सीखना होगा। मापें कि आप क्या कर रहे हैं और यह विश्वास न करें कि सीटीई, टेम्प टेबल्स या कर्सर बुराई हैं। उपाय - क्योंकि सच्चाई परिदृश्य पर निर्भर करती है।
डेव हिल्डिच

@DaveHilditch यह एक उचित टिप्पणी है, लेकिन यह भी निष्पक्ष टिप्पणी है कि बहुत, बहुत सारी स्थितियों में, कर्सर सही समाधान नहीं हैं, इसलिए यह उनके लिए एक व्यावहारिक सामान्यीकरण है, साथ ही लगभग एक अंतिम उपाय भी है।
मेल पैडेन

1
मेरे अनुभव में, एक कसूर अपने आप में बुरा नहीं है। डेवलपर्स आमतौर पर "गलत तरीके से" डेवलपर्स द्वारा उपयोग किए जाते हैं, क्योंकि अधिकांश प्रोग्रामिंग भाषाओं में, आपको एसर का विरोध करना पड़ता है, जहां आपको ज्यादातर बैचों में सोचना पड़ता है। मुझे पता है कि यह मेरे कार्यस्थल पर एक सामान्य गलती है जहाँ देवता सिर्फ CURSOR के अलावा किसी समस्या से बाहर निकलने का रास्ता नहीं देख सकते हैं, इस प्रकार एक अच्छा DBA उन्हें सिखाने और उन्हें ठीक करने के काम में आता है। @DaveHilditch पूरी तरह से सही है: सही काम के लिए सही उपकरण यह सब लेता है।
फिलिप

14

CTE को क्वेरी के भीतर बार-बार बुलाया जा सकता है और इसका संदर्भ लिए जाने पर हर बार मूल्यांकन किया जाता है - यह प्रक्रिया पुनरावर्ती हो सकती है। यदि इसे सिर्फ एक बार संदर्भित किया जाता है तो यह एक उप-क्वेरी की तरह व्यवहार करता है, हालांकि सीटीई को पैरामीटर किया जा सकता है।

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

IIRC तालिका चर (दूसरी ओर) हमेशा स्मृति संरचनाओं में होती हैं।


4
CTEs को मानकीकृत किया जा सकता है? कैसे? इसके अलावा, टेबल चर हमेशा स्मृति संरचनाओं में नहीं होते हैं । संबंधित प्रश्न के लिए मार्टिन का उत्कृष्ट उत्तर देखें ।
पॉल व्हाइट

11

Temp टेबल टेम्पप में एक वास्तविक ऑब्जेक्ट है, लेकिन cte केवल एक प्रकार का आवरण है जो जटिल क्वेरी के चारों ओर एक चरण में पुनरावृत्ति को व्यवस्थित करने के सिंटैक्स को सरल करता है।


8

CTEs का उपयोग करने का प्राथमिक कारण विंडो फ़ंक्शंस जैसे row_number()और विभिन्न अन्य का उपयोग करना है।

इसका अर्थ यह है कि आप समूह की पहली या अंतिम पंक्ति प्राप्त कर सकते हैं जैसे बहुत जल्दी और कुशलता से - अधिकांश व्यावहारिक मामलों में अन्य साधनों की तुलना में अधिक कुशलता से

with reallyfastcte as (
select *, 
row_number() over (partition by groupingcolumn order by sortingcolumn) as rownum
from sometable
)
select *
from reallyfastcte
where rownum = 1;

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

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

इसके अतिरिक्त, सीटीई प्रदर्शन को बढ़ावा दे सकता है यदि आप अपने व्यापार तर्क को समझते हैं और जानते हैं कि क्वेरी के किन हिस्सों को पहले चलाया जाना चाहिए - आम तौर पर, अपने सबसे चुनिंदा प्रश्नों को पहले रखें, जिसके परिणामस्वरूप परिणाम सेट होते हैं जो अपने अगले जॉइन में एक इंडेक्स का उपयोग कर सकते हैं और option(force order)क्वेरी जोड़ सकते हैं। संकेत

अंत में, CTE डिफ़ॉल्ट रूप से tempdb का उपयोग नहीं करते हैं ताकि आप उनके उपयोग के माध्यम से उस अड़चन पर विवाद को कम कर सकें।

यदि आप अपने प्रश्नों को मापते हैं और वैकल्पिक रूप से एक टेम्‍प टेबल में सम्मिलित करते हैं और फिर एक इंडेक्स जोड़ते हैं जिससे आपके प्रदर्शन में सुधार होता है तो अस्थायी तालिकाओं का उपयोग कई बार डेटा को क्वेरी करने या वैकल्पिक रूप से करने की आवश्यकता होती है।


सभी अच्छे अंक ... +1
मेल पैडेन

6

सीटीई के प्रति यहां थोड़ी नकारात्मकता दिख रही है।

CTE की मेरी समझ यह है कि यह मूल रूप से एक प्रकार का एडहॉक दृश्य है। एसक्यूएल एक घोषणात्मक और एक सेट आधारित भाषा दोनों है। CTE एक सेट घोषित करने का एक शानदार तरीका है! CTE को इंडेक्स करने में सक्षम नहीं होना वास्तव में एक अच्छी बात है क्योंकि आपको इसकी आवश्यकता नहीं है! यह वास्तव में एक प्रकार का वाक्यात्मक चीनी है जिससे क्वेरी को पढ़ने / लिखने में आसानी होती है। कोई भी सभ्य ऑप्टिमाइज़र अंतर्निहित तालिकाओं पर अनुक्रमित का उपयोग करके सबसे अच्छी पहुंच योजना का काम करेगा। इसका अर्थ है कि आप अंतर्निहित तालिकाओं पर सूचकांक सलाह का पालन करके अपनी CTE क्वेरी को प्रभावी ढंग से तेज़ कर सकते हैं।

इसके अलावा, सिर्फ इसलिए कि आपने एक सेट को सीटीई के रूप में परिभाषित किया है, इसका मतलब यह नहीं है कि सेट में सभी पंक्तियों को संसाधित किया जाना चाहिए। क्वेरी पर आश्रित ऑप्टिमाइज़र क्वेरी को संतुष्ट करने के लिए "बस पर्याप्त" पंक्तियों को संसाधित कर सकता है। हो सकता है कि आपको केवल अपनी स्क्रीन के लिए पहले 20 या इतने की आवश्यकता थी। यदि आपने एक अस्थायी तालिका बनाई है, तो आपको वास्तव में उन सभी पंक्तियों को पढ़ने / लिखने की आवश्यकता है!

इसके आधार पर मैं यह कहूंगा कि सीटीई एसक्यूएल की एक बड़ी विशेषता है और इसका उपयोग कहीं भी किया जा सकता है, जिससे उन्हें पढ़ने में आसानी हो। मैं केवल एक बैच प्रक्रिया के लिए एक अस्थायी तालिका के बारे में सोचूंगा जो वास्तव में हर एक रिकॉर्ड को संसाधित करने की आवश्यकता होगी। तब भी afaik यह वास्तव में अनुशंसित नहीं है क्योंकि एक अस्थायी तालिका पर यह डेटाबेस के लिए आपको कैशिंग और इंडेक्स के साथ मदद करने के लिए बहुत कठिन है। अपने लेनदेन के लिए एक PK फ़ील्ड के साथ एक स्थायी तालिका रखना बेहतर हो सकता है।

मुझे यह स्वीकार करना होगा कि मेरा अनुभव मुख्य रूप से डीबी 2 के साथ है इसलिए मैं मान रहा हूं कि सीटीई का काम दोनों उत्पादों में समान रूप से है। यदि CTE SQL सर्वर में किसी तरह से हीन हैं तो मैं खुशी से सही खड़ा हो जाऊंगा। ;)

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