2009-06-14 12 views
5

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

SELECT * 
FROM A 
INNER JOIN B 
ON B.id = A.id 
INNER JOIN C 
ON C.id = A.id 

जो निश्चित रूप से पूरी तरह से काम करता है।

हाल ही में, हमारे डीबीए हमें बताया कि इस Oracle में अक्षम है, और आप इस प्रकार, सी और बी के बीच की स्थिति में शामिल होने के रूप में अच्छी तरह की जरूरत है: इसलिए स्वाभाविक रूप से मैं नहीं था

SELECT * 
FROM A 
INNER JOIN B 
ON B.id = A.id 
INNER JOIN C 
ON C.id = A.id AND C.id = B.id 

यह मेरे लिए बेमानी देखा, यहाँ विश्वास नहीं है। जब तक कि मैं वास्तव में एक धीमी क्वेरी में भाग नहीं लेता था, जिसमें एक भयानक निष्पादन योजना थी, और गायब होने की स्थिति को ठीक से जोड़कर इसे ठीक करने में कामयाब रहा। मैंने दोनों संस्करणों पर योजना की व्याख्या की: एक "अनावश्यक" क्वेरी शर्त के बिना 1 035 की लागत थी, जबकि "बेहतर" में 38 9 थे (और कार्डिनिटी और बाइट्स में भी बहुत अंतर थे)। दोनों प्रश्नों ने सटीक उसी परिणाम का उत्पादन किया।

क्या कोई यह समझा सकता है कि यह अतिरिक्त स्थिति क्यों फर्क पड़ती है? मेरे लिए सी और बी भी संबंधित नहीं हैं। ध्यान दें कि यदि आप अन्य शामिल स्थिति को दूर करते हैं तो यह भी उतना ही बुरा है - दोनों को वहां रहने की आवश्यकता है।

उत्तर

2

आपको जो मिला है वह दो मुद्दे हैं।

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

अब, आप अनावश्यक स्थिति जोड़ते हैं। ओरेकल मानता है कि कोई भी स्थिति वास्तव में अनावश्यक नहीं है (जैसे, यदि वे थे, तो एक बुद्धिमान डेवलपर उन्हें शामिल नहीं करेगा)। यह भी मानता है कि प्रत्येक शर्त दूसरों से स्वतंत्र है। उदाहरण के लिए, एक चयन जहां बाल = 'गंजा' तालिका के 10% हो सकता है, एक चयन जहां लिंग = 'एफ' 50% हो सकता है। ओरेकल मान लेगा कि एक चयन जहां बाल = 'गंजा' और लिंग = 'एफ' 5% देगा (जबकि वास्तविकता में गंजापन ज्यादातर पुरुषों तक ही सीमित है)।

'अनावश्यक' भविष्यवाणी जोड़कर, ओरेकल संख्याओं या पंक्तियों को बहिष्कृत करने का अनुमान लगाएगा और तदनुसार योजना का चयन करेगा।

यदि अनावश्यक भविष्यवाणी के साथ, ओरेकल एक बेहतर योजना चुन रहा है, तो यह सुझाव देता है कि मूल क्वेरी के अनुमानों की अनुमानित पंक्तियों की संख्या अनुमानित है। अनावश्यक भविष्यवाणी एक अनुमान के साथ सामना कर रही है। और इस मामले में, दो गलत अधिकार बना रहे हैं।

यह एक समाधान मैं सलाह देते हैं नहीं है, लेकिन अगर यह काम करता है .....

पी एस। मुझे लगता है कि सभी आईडी के डेटा प्रकार सुसंगत हैं। यदि बीआईडी ​​और सीआईडी ​​तारीख हैं और एआईडी चरित्र था, या इसके विपरीत, तो कुछ पंक्तियां हो सकती हैं जहां एआईडी = बीआईडी ​​और एआईडी = सीआईडी ​​लेकिन बीआईडी! = सीआईडी, क्योंकि निहित रूपांतरण टाइमस्टैम्प खो सकता है।

+1

दोनों थे, मैं आपसे सहमत हूं गैरी: यदि योजना अनावश्यक स्थिति में शामिल होने के साथ बेहतर है, तो ऐसा इसलिए है क्योंकि आंकड़े गलत हैं। आम तौर पर, आपको अनावश्यक जानकारी प्रदान नहीं करनी चाहिए। –

+0

यह मेरे लिए सबसे अधिक आकर्षक जवाब है, क्योंकि यह ओरेकल में कुछ आशा बहाल करता है। (तो हाँ, मैं थोड़ा सा पक्षपातपूर्ण पक्षपातपूर्ण हूं।) क्या किसी के जवाब देने के लिए वास्तविक स्पष्टीकरण मुश्किल है। – waxwing

1

उन दो प्रश्नों को बिल्कुल मेरे जैसा नहीं दिखता है।
फिर फिर मैं ओरेकल अनुकूलक नहीं हूं। चूंकि दोनों बी और सी ए का विदेशी कुंजी है जब आप इस

INNER JOIN B 
ON B.id = A.id 

परिणामी resultset किया है

(का कहना है कि कई बार तेजी से) जिस पर आप अपने दूसरे प्रश्न में तालिका सी में शामिल होने छोटा होता है, जैसा कि आपने अपने निष्पादन-योजना परिणामों में देखा है, यह तब होता है जब आप तालिका सी तालिका में आपकी पहली क्वेरी के रूप में पूरी तरह से में शामिल होते हैं।

दूसरे प्रश्न में तो तुम अनुकूलन किया है बातें डेटा के छोटे सेट कि ए और बी, और डेटा के छोटे सेट के चौराहे कि ए और सी के चौराहे है पर तालिका सी में शामिल होने से

+1

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

+0

@ डेव: उस पूरी व्याख्या के लिए धन्यवाद। मुझे लगता है कि मैंने इस सवाल का खराब जवाब देने से बहुत कुछ सीखा है। उम्मीद है कि कोई और भी इससे सीख सकता है। – bernie

2

ओरेकल के अनुकूलक समानता के बारे में संक्रमणीय मान्यताओं को नहीं बनाते हैं। हालांकि हम समझते हैं कि यदि ए = बी और ए = सी, तो बी = सी, ओरेकल यह नहीं मानता है कि बी & सी के बीच कोई संबंध नहीं है जब तक कि WHERE क्लॉज या जॉइन स्थितियों में स्पष्ट रूप से कोई नहीं बताया गया हो।

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

+0

हां, आपकी धारणा सही है। वास्तव में, जब मैंने यह प्रश्न लिखा था, तो मुझे मूल क्वेरी भी नहीं मिल सका, इसलिए मैंने कहा कि संबंधों के साथ तीन तालिकाओं सहित एक समान लिखा है। मेरे पास एक स्याही है कि वास्तविक क्वेरी ने और भी नाटकीय मतभेद पैदा किए। हालांकि, मैंने केवल बी = सी शर्त (लेकिन ए = सी) की स्थिति को शामिल करने के लिए (मूल क्वेरी के साथ) कोशिश की, और इसी तरह के खराब परिणाम मिल गए। मेरे लिए अजीब बात यह थी कि मुझे ए = सी और बी = सी – waxwing

3

दिलचस्प।

ऐसा लगता है कि ओरेकल केवल कुछ परिस्थितियों में इस संक्रमणीय समानता का अनुमान लगा सकता है: वे इसे Transitive Closure कहते हैं और क्वेरी रीराइटिंग सक्षम होने पर आपको इसका लाभ उठाने में सक्षम होना चाहिए।

लेकिन सुरक्षित पक्ष पर रहने के लिए, अनावश्यक भविष्यवाणी को बेहतर तरीके से बताएं।

+0

दिलचस्प लेख। धन्यवाद! – waxwing

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