2015-03-17 14 views
6

कृपया क्वेरी के इन दो प्रकार आपके मन में आने:'जहां उसके बाद संघ' का उपयोग करना या का उपयोग करते हुए यूनियन तो कहाँ '

--query1 
Select someFields 
From someTables 
Where someWhereClues 
Union all 
Select someFields 
FROM some Tables 
Where someWhereClues 

--query2 
Select * FROM (
    Select someFields 
    From someTables 
    Union all 
    Select someFields 
    FROM someTables 
    ) DT 
Where someMixedWhereClues 

नोट:
दोनों प्रश्नों अंतिम परिणाम क्षेत्रों में ही कर रहे हैं

मैंने पहले सोचा था। क्वेरी तेज है या इसका प्रदर्शन बेहतर है!
लेकिन कुछ शोध के बाद मैं इस note से उलझन में:

एसक्यूएल सर्वर (के रूप में आरडीबीएमएस का एक नमूना) पहले पढ़ता पूरे डेटा तो रिकॉर्ड करना चाहते हैं। => इसलिए दोनों प्रश्नों में सभी रिकॉर्ड पढ़ेंगे और खोजेंगे।

कृपया मेरी गलतफहमी पर मेरी सहायता करें, और यदि क्वेरी 1 और क्वेरी 2 के बीच कोई अन्य अंतर है?


संपादित: जोड़ने नमूना योजनाओं:

select t.Name, t.type from sys.tables t where t.type = 'U' 
union all 
select t.Name, t.type from sys.objects t where t.type = 'U' 

select * from (
    select t.Name, t.type from sys.tables t 
    union all 
    select t.Name, t.type from sys.objects t 
    ) dt 
where dt.type = 'U' 

निष्पादन योजनाओं हैं: enter image description here enter image description here

ही दोनों कर रहे हैं और 50%

+0

आप दोनों प्रश्नों पर निष्पादन योजना चलाकर क्या हो रहा है, यह जांच सकते हैं। –

+0

यदि आप अपने दिए गए डेटा के लिए निष्पादन योजनाएं और सर्वर आंकड़े (समय/आईओ) की जांच करते हैं, तो आप देख सकते हैं कि कौन सा बेहतर है। मेरे सिर के ऊपर से, पहला एक बेहतर दिखता है, लेकिन एसक्यूएल सर्वर ऑप्टिमाइज़र दोनों बराबर बनाने के लिए पर्याप्त स्मार्ट हो सकता है। इसलिए - यह देखने का तरीका है कि इसका विश्लेषण करने का तरीका क्या है। –

+0

मैं निष्पादन योजना भी जोड़ता हूं !!?? –

उत्तर

0

मेरी प्रैक्टिस में पहला विकल्प दूसरे की तुलना में धीमा नहीं था। मुझे लगता है कि ऑप्टिमाइज़र इन योजनाओं को समान रूप से कम या ज्यादा अनुकूलित करने के लिए पर्याप्त स्मार्ट है। हालांकि मैंने कुछ परीक्षण किए और पहला विकल्प हमेशा बेहतर था। उदाहरण के लिए:

CREATE TABLE #a (a INT, b INT); 

WITH Numbers (I) AS (
    SELECT 1000 

    UNION ALL 

    SELECT I + 1 
    FROM Numbers 
    WHERE I < 5000 
) 
INSERT INTO #a (a) 
SELECT I 
FROM Numbers 
ORDER BY CRYPT_GEN_RANDOM(4) 
OPTION (MAXRECURSION 0); 

WITH Numbers (I) AS (
    SELECT 1000 

    UNION ALL 

    SELECT I + 1 
    FROM Numbers 
    WHERE I < 5000 
) 
INSERT INTO #a (b) 
SELECT I 
FROM Numbers 
ORDER BY CRYPT_GEN_RANDOM(4) 
OPTION (MAXRECURSION 0); 

SELECT a, b 
FROM #a 
WHERE a IS NOT NULL 
UNION ALL 
SELECT a, b 
FROM #a 
WHERE b IS NOT NULL 

SELECT * 
FROM (
    SELECT a, b 
    FROM #a 
    UNION ALL 
    SELECT a, b 
    FROM #a 
    ) c 
WHERE a IS NOT NULL 
    OR b IS NOT NULL 

परिणाम 47% 53% बनाम

+0

जैसा कि मैंने 'यूनियन ऑल' का नतीजा पाया है, बेहतर है कि 'OR' का उपयोग करके अपने प्रश्नों को 'जहां कोई नल नहीं है' पर क्लिक करें और फिर उन्हें जांचें, और यदि आपने परिणामों की जांच की है तो आप देख सकते हैं कि आपकी पहली क्वेरी '8002' पंक्तियां लौटाती हैं और दूसरा एक '16004' पंक्तियां देता है, इसलिए वे समान नहीं होते हैं। –

0

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

1

पहला व्यक्ति धीमा नहीं हो सकता है।

  • पहले में WHERE खंड कुशलता से एक INDEX का उपयोग कर सकते हैं, तो वहाँ कम पंक्तियां UNION में एक साथ इकट्ठा करने के लिए किया जाएगा: यहाँ तर्क है। कम पंक्तियां -> तेज़।
  • दूसरे में UNION पर नहीं है, इसलिए WHERE को इस तरह अनुकूलित नहीं किया जा सकता है।

यहां कुछ चीजें हैं जो पहले धीमे होने का कारण बन सकती हैं। लेकिन मैं उन्हें अपवाद के रूप में देखता हूं, नियम नहीं।

  • समांतरता की एक अलग राशि हासिल की जाती है।
  • जब आप क्वेरी चलाते हैं तो अलग-अलग सामान कैश किए जाते हैं।

चेतावनी: मुझे लगता है कि सभी तीन WHERE क्लॉज समान हैं (जैसा कि आपका उदाहरण दिखाता है)।

+0

'कम पंक्तियां -> तेज़' मेरे दिमाग में यह ऐसा था लेकिन [इस आलेख को देखें कि SQL सर्वर क्वेरी कैसे निष्पादित करता है] (www.codeproject.com/Articles/630346/Understanding-how-SQL- सर्वर -एक्सक्यूट्स-ए-क्वेरी), प्रश्नों पर मेरे नोट वहां से आते हैं;)। –

+0

लंबे लेख (और अच्छा)। इसका क्या विशेष हिस्सा यहां प्रासंगिक है? –

5

SQL Server query optimizer, दोनों प्रश्नों को अनुकूलित करता है ताकि आपको लगभग समान प्रदर्शन मिल सके।

+2

यह एक अच्छा लिंक है, धन्यवाद;)। –

1

अंगूठे के नियम के रूप में, मैं हमेशा पहली प्रकार की क्वेरी का उपयोग करने पर विचार करता हूं।

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

0

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

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

संबंधित मुद्दे