कौन से कलाकार अधिक हैं, CTE
या Temporary Tables
?
कौन से कलाकार अधिक हैं, CTE
या Temporary Tables
?
जवाबों:
मैं कहता हूं कि वे अलग अवधारणाएं हैं, लेकिन "चॉक और पनीर" कहने के लिए बहुत अलग नहीं हैं।
डेटा के एक सेट पर पुन: उपयोग करने या कई प्रसंस्करण पास करने के लिए एक अस्थायी तालिका अच्छी है।
एक सीटीई का उपयोग या तो पुनरावृत्ति के लिए या केवल पठनीयता में सुधार के लिए किया जा सकता है।
और, एक दृश्य या इनलाइन तालिका मूल्यवान फ़ंक्शन की तरह भी मुख्य क्वेरी में विस्तारित होने के लिए मैक्रो की तरह व्यवहार किया जा सकता है
एक अस्थायी तालिका एक और तालिका है जिसमें कुछ नियम हैं
मैंने जहाँ मैं (और तालिका चर दोनों) का उपयोग करता है, वहां प्रोक्स संग्रहीत किए हैं
cte vs temporary tables
तो IMHO इस उत्तर को CTE के बेहतर कमियों को उजागर करने की आवश्यकता है। लिंक किए गए उत्तर के टीएल; डीआर: एक सीटीई का उपयोग प्रदर्शन के लिए कभी नहीं किया जाना चाहिए। । मैं उस उद्धरण से सहमत हूं क्योंकि मैंने सीटीई के डाउनसाइड्स का अनुभव किया है।
निर्भर करता है।
सबसे पहले
कॉमन टेबल एक्सप्रेशन क्या है?
A (गैर पुनरावर्ती) CTE को अन्य निर्माणों के समान माना जाता है जिनका उपयोग SQL सर्वर में इनलाइन टेबल एक्सप्रेशन के रूप में भी किया जा सकता है। व्युत्पन्न टेबल, दृश्य और इनलाइन तालिका मूल्यवान कार्य। ध्यान दें कि बीओएल का कहना है कि एक सीटीई "को अस्थायी परिणाम सेट के रूप में माना जा सकता है" यह एक विशुद्ध रूप से तार्किक विवरण है। अधिक बार नहीं यह अपने आप में मातृसत्तात्मक नहीं है।
अस्थायी तालिका क्या है?
यह tempdb में डेटा पृष्ठों पर संग्रहीत पंक्तियों का एक संग्रह है। डेटा पेज आंशिक रूप से या पूरी तरह से मेमोरी में रह सकते हैं। इसके अतिरिक्त अस्थायी तालिका को अनुक्रमित किया जा सकता है और कॉलम आँकड़े हो सकते हैं।
परीक्षण डेटा
CREATE TABLE T(A INT IDENTITY PRIMARY KEY, B INT , F CHAR(8000) NULL);
INSERT INTO T(B)
SELECT TOP (1000000) 0 + CAST(NEWID() AS BINARY(4))
FROM master..spt_values v1,
master..spt_values v2;
उदाहरण 1
WITH CTE1 AS
(
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
)
SELECT *
FROM CTE1
WHERE A = 780
ऊपर की योजना में सूचना CTE1 का कोई उल्लेख नहीं है। यह बस बेस टेबल को सीधे एक्सेस करता है और इसे उसी तरह माना जाता है
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
WHERE A = 780
CTE को इंटरमीडिएट अस्थायी तालिका में शामिल करके फिर से तैयार करना बड़े पैमाने पर उत्पादक होगा।
की सीटीई परिभाषा को भौतिक बनाना
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
एक अस्थायी तालिका में लगभग 8GB डेटा की नकल करना शामिल होगा, फिर भी उसमें से चयन करने का ओवरहेड अभी भी है।
उदाहरण 2
WITH CTE2
AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0)
SELECT *
FROM CTE2 T1
CROSS APPLY (SELECT TOP (1) *
FROM CTE2 T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
उपरोक्त उदाहरण मेरी मशीन पर लगभग 4 मिनट लगते हैं।
1,000,000 यादृच्छिक रूप से उत्पन्न मानों की केवल 15 पंक्तियाँ विधेय से मेल खाती हैं लेकिन इनको खोजने के लिए महंगी तालिका स्कैन 16 बार होता है।
यह मध्यवर्ती परिणाम के लिए एक अच्छा उम्मीदवार होगा। समतुल्य अस्थायी तालिका पुनर्लेखन में 25 सेकंड लगे।
INSERT INTO #T
SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0
SELECT *
FROM #T T1
CROSS APPLY (SELECT TOP (1) *
FROM #T T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
एक अस्थायी तालिका में एक क्वेरी के हिस्से का मध्यवर्ती भौतिककरण कभी-कभी उपयोगी हो सकता है, भले ही इसका मूल्यांकन केवल एक बार किया जाए - जब यह क्वेरी के बाकी हिस्सों को भौतिक परिणाम पर आँकड़ों का लाभ लेने की अनुमति देता है। इस दृष्टिकोण का एक उदाहरण SQL कैट के लेख में है जब कॉम्प्लेक्स क्वेरीज़ को तोड़ना है ।
कुछ परिस्थितियों में SQL सर्वर एक स्पूल का उपयोग एक मध्यवर्ती परिणाम को कैश करने के लिए करेगा, उदाहरण के लिए एक सीटीई, और इस उप-वृक्ष का पुनर्मूल्यांकन करने से बचें। इसमें (माइग्रेट किए गए) कनेक्ट आइटम पर चर्चा की गई है जो सीटीई या व्युत्पन्न तालिकाओं के मध्यवर्ती भौतिककरण को मजबूर करने के लिए एक संकेत प्रदान करता है । हालाँकि, इस पर कोई आंकड़े नहीं बनाए गए हैं और भले ही स्पूल की गई पंक्तियों की संख्या अनुमानित रूप से भिन्न हो, प्रगति निष्पादन योजना के गतिशील रूप से प्रतिक्रिया में अनुकूल होने के लिए संभव नहीं है (कम से कम वर्तमान संस्करणों में। अनुकूली क्वेरी योजनाएँ संभव हो सकती हैं। भविष्य)।
सीटीई के अपने उपयोग हैं - जब सीटीई में डेटा छोटा होता है और पुनरावर्ती तालिकाओं में मामले के साथ मजबूत पठनीयता में सुधार होता है। हालांकि, इसका प्रदर्शन निश्चित रूप से टेबल चर से बेहतर नहीं है और जब कोई बहुत बड़ी तालिकाओं के साथ काम कर रहा है, तो अस्थायी तालिकाओं में सीटीई से बेहतर प्रदर्शन होता है। इसका कारण यह है कि आप CTE पर सूचकांकों को परिभाषित नहीं कर सकते हैं और जब आपके पास बड़ी मात्रा में डेटा है जिसे किसी अन्य तालिका के साथ जुड़ने की आवश्यकता होती है (CTE एक मैक्रो की तरह है)। यदि आप प्रत्येक में लाखों पंक्तियों के साथ कई तालिकाओं में शामिल हो रहे हैं, तो CTE अस्थायी तालिकाओं की तुलना में काफी खराब प्रदर्शन करेगा।
टेंप टेबल हमेशा डिस्क पर होती हैं - इसलिए जब तक आपकी सीटीई को मेमोरी में रखा जा सकता है, तब तक इसकी संभावना सबसे तेज होगी (जैसे टेबल वेरिएबल भी)।
लेकिन फिर, यदि आपके CTE (या अस्थायी तालिका चर) का डेटा लोड बहुत बड़ा हो जाता है, तो इसे डिस्क पर संग्रहीत किया जाएगा, इसलिए कोई बड़ा लाभ नहीं है।
सामान्य तौर पर, मैं एक अस्थायी तालिका के ऊपर एक सीटीई पसंद करता हूं क्योंकि इसका उपयोग करने के बाद यह चला गया है। मुझे इसे स्पष्ट रूप से या कुछ भी छोड़ने के बारे में सोचने की आवश्यकता नहीं है।
इसलिए, अंत में कोई स्पष्ट जवाब नहीं है, लेकिन व्यक्तिगत रूप से, मैं अस्थायी टेबल पर सीटीई पसंद करूंगा।
इसलिए जो क्वेरी मुझे ऑप्टिमाइज़ करने के लिए दी गई थी, वह SQL सर्वर में दो CTE के साथ लिखी गई थी। इसमें 28 सेकेंड का समय लग रहा था।
मैंने उन्हें टेम्प टेबल में बदलने में दो मिनट का समय लगाया और क्वेरी को 3 सेकंड का समय लगा
जिस फील्ड में यह शामिल हो रहा था, उस पर मैंने टेम्पर टेबल में एक इंडेक्स जोड़ा और इसे 2 सेकंड तक नीचे कर दिया
तीन मिनट का काम और अब CTE को हटाकर इसका रनिंग 12 गुना तेज हो गया है। मैं व्यक्तिगत रूप से सीटीई का उपयोग नहीं करूंगा, वे कभी-कभी डिबग करने के लिए कठिन हैं।
पागल बात यह है कि सीटीई दोनों केवल एक बार उपयोग किए गए थे और अभी भी उन पर एक इंडेक्स डालना 50% तेज साबित हुआ।
CTE कोई भौतिक स्थान नहीं लेगा। यह सिर्फ एक परिणाम है जो हम शामिल होने का उपयोग कर सकते हैं।
अस्थायी टेबल अस्थायी हैं। हम सभी तालिकाओं को परिभाषित करने के लिए सामान्य तालिकाओं की तरह अनुक्रमित, बाधाएं बना सकते हैं।
केवल सत्र के भीतर अस्थायी तालिका का दायरा। EX: दो SQL क्वेरी विंडो खोलें
create table #temp(empid int,empname varchar)
insert into #temp
select 101,'xxx'
select * from #temp
इस क्वेरी को पहले विंडो में चलाएं फिर नीचे की क्वेरी को दूसरी विंडो में चलाएं आप अंतर पा सकते हैं।
select * from #temp
मैंने दोनों का उपयोग किया है, लेकिन बड़े जटिल प्रक्रियाओं में हमेशा अस्थायी तालिकाओं को बेहतर और अधिक व्यवस्थित रूप से काम करने के लिए मिला है। CTE के अपने उपयोग हैं लेकिन आम तौर पर छोटे डेटा के साथ।
उदाहरण के लिए, मैंने 15 सेकंड में बड़ी गणनाओं के परिणामों के साथ वापस आने वाले स्प्रोक्स बनाए हैं, फिर भी इस कोड को एक सीटीई में चलाने के लिए परिवर्तित करते हैं और समान परिणाम प्राप्त करने के लिए इसे 8 मिनट से अधिक समय तक चलते देखा है।
पार्टी के लिए देर से, लेकिन ...
जिस वातावरण में मैं काम करता हूं वह अत्यधिक विवश है, कुछ विक्रेता उत्पादों का समर्थन करता है और रिपोर्टिंग जैसी "मूल्य वर्धित" सेवाएं प्रदान करता है। नीति और अनुबंध सीमाओं के कारण, मुझे आमतौर पर अलग-अलग टेबल / डेटा स्पेस की लक्जरी और / या स्थायी कोड बनाने की क्षमता की अनुमति नहीं दी जाती है [यह आवेदन के आधार पर थोड़ा बेहतर हो जाता है]।
IOW, मैं नहीं कर सकता आमतौर पर एक संग्रहीत कार्यविधि या UDFs या अस्थायी सारणी आदि विकसित । मुझे अपने एप्लीकेशन इंटरफेस (क्रिस्टल रिपोर्ट्स - ऐड / लिंक टेबल्स) के माध्यम से सब कुछ करना है, जहाँ से CR में w / से क्लॉस आते हैं, आदि। )। एक लघु बचत अनुग्रह यह है कि क्रिस्टल मुझे COMMANDS (साथ ही SQL एक्सप्रेशंस) का उपयोग करने की अनुमति देता है। कुछ चीजें जो नियमित ऐड / लिंक टेबल क्षमता के माध्यम से कुशल नहीं हैं, उन्हें SQL कमांड को परिभाषित करके किया जा सकता है। मैं उस के माध्यम से सीटीई का उपयोग करता हूं और "दूरस्थ रूप से" बहुत अच्छे परिणाम प्राप्त करता हूं। CTEs w / रिपोर्ट रखरखाव में मदद करते हैं, उस कोड को विकसित करने की आवश्यकता नहीं है, संकलन, एन्क्रिप्ट, स्थानांतरण, इंस्टॉल करने के लिए DBA को सौंप दिया जाता है, और फिर कई-स्तरीय परीक्षण की आवश्यकता होती है। मैं स्थानीय इंटरफ़ेस के माध्यम से सीटीई कर सकता हूं।
CTEs w / CR का उपयोग करने का डाउन साइड है, प्रत्येक रिपोर्ट अलग है। प्रत्येक रिपोर्ट के लिए प्रत्येक सीटीई को बनाए रखा जाना चाहिए। जहां मैं एसपी और यूडीएफ कर सकता हूं, मैं एक ऐसी चीज विकसित कर सकता हूं जिसका उपयोग कई रिपोर्टों द्वारा किया जा सकता है, केवल एसपी से लिंक करने और मापदंडों को पारित करने की आवश्यकता होती है जैसे कि आप एक नियमित टेबल पर काम कर रहे थे। सीआर वास्तव में एसक्यूएल कमांड में मापदंडों को संभालने के लिए अच्छा नहीं है, ताकि सीआर / सीटीई पहलू के पहलू की कमी हो सकती है। उन मामलों में, मैं आमतौर पर पर्याप्त डेटा (लेकिन सभी डेटा नहीं) वापस करने के लिए सीटीई को परिभाषित करने की कोशिश करता हूं, और फिर सीआर में रिकॉर्ड चयन क्षमताओं का उपयोग स्लाइस और पासा करने के लिए करता हूं।
इसलिए ... मेरा वोट सीटीई के लिए है (जब तक मुझे अपना डेटा स्पेस नहीं मिल जाता)।
एक उपयोग जहां मुझे CTE का उत्कृष्ट प्रदर्शन बुद्धिमान मिला, वह यह था कि मुझे कुछ तालिकाओं पर अपेक्षाकृत जटिल क्वेरी में शामिल होने की आवश्यकता थी, जिसमें कुछ मिलियन पंक्तियाँ थीं।
मैंने सबसे पहले CTE का उपयोग अनुक्रमित स्तंभों के आधार पर सबसे पहले इन तालिकाओं को काटकर कुछ हज़ार प्रासंगिक पंक्तियों में करने के लिए किया और फिर CTE को मेरी मुख्य क्वेरी में शामिल किया। इसने तेजी से मेरी क्वेरी के रनटाइम को कम कर दिया।
सीटीई के लिए जब भी नतीजे कैश नहीं होते हैं और टेबल वेरिएबल एक बेहतर विकल्प हो सकता है, तो मैं वास्तव में बस उन्हें आज़माना चाहता था और फिट होना चाहिए।
यह वास्तव में खुला हुआ प्रश्न है, और यह सब इस बात पर निर्भर करता है कि इसका उपयोग कैसे किया जा रहा है और टेम्प टेबल का प्रकार (टेबल चर या पारंपरिक तालिका)।
एक पारंपरिक अस्थायी तालिका डेटा को अस्थायी DB में संग्रहीत करती है, जो अस्थायी तालिकाओं को धीमा कर देती है; हालांकि टेबल चर नहीं है।
मैंने अभी इसका परीक्षण किया- सीटीई और गैर-सीटीई (जहां हर यूनियन उदाहरण के लिए क्वेरी टाइप की गई थी) दोनों ने ~ 31 सेकंड का समय लिया। CTE ने कोड को अधिक पठनीय बना दिया, हालांकि इसे 241 से 130 लाइनों तक काट दिया जो बहुत अच्छा है। दूसरी ओर अस्थायी तालिका ने इसे 132 रेखाओं तक काट दिया, और चलाने के लिए FIVE SECONDS लिया। कोई मजाक नहीं। इस परीक्षण के सभी को कैश किया गया था - प्रश्न पहले सभी कई बार चलाए गए थे।
SQL सर्वर में अपने अनुभव से, मुझे एक परिदृश्य मिला जहां CTE ने टेम्पर टेबल को बेहतर बनाया
मुझे एक जटिल क्वेरी से डेटासेट (~ 100000) का उपयोग करने की आवश्यकता थी बस मेरे संग्रहीत कार्यविधि में ONCE।
टेंप टेबल एसक्यूएल पर एक ओवरहेड का कारण बन रही थी जहां मेरी प्रक्रिया धीरे-धीरे प्रदर्शन कर रही थी (जैसे कि टेंप टेबल्स वास्तविक भौतिक तालिकाओं हैं जो टेम्पर्डब में मौजूद हैं और मेरी वर्तमान प्रक्रिया के जीवन के लिए जारी रहती हैं)
दूसरी ओर, सीटीई के साथ, सीटीई पर्सिस्ट केवल तभी तक चलता है जब तक कि निम्नलिखित क्वेरी नहीं चलती। तो, CTE सीमित स्कोप के साथ एक आसान स्मृति संरचना है। CTE डिफ़ॉल्ट रूप से tempdb का उपयोग नहीं करते हैं।
यह एक ऐसा परिदृश्य है जहां सीटीई वास्तव में आपके कोड और आउटपरफॉर्म टेम्प टेबल को सरल बनाने में मदद कर सकता है। मैंने 2 सीटीई का उपयोग किया था, कुछ ऐसा
WITH CTE1(ID, Name, Display)
AS (SELECT ID,Name,Display from Table1 where <Some Condition>),
CTE2(ID,Name,<col3>) AS (SELECT ID, Name,<> FROM CTE1 INNER JOIN Table2 <Some Condition>)
SELECT CTE2.ID,CTE2.<col3>
FROM CTE2
GO