2008-12-17 16 views
6

मैं किसी और के PHP कोड पर काम कर रहा हूँ और अधिक इस पैटर्न को देखने और:बायाँ शामिल हों बनाम कई SELECT स्टेटमेंट्स

(स्यूडोकोड)

result = SELECT blah1, blah2, foreign_key FROM foo WHERE key=bar 

if foreign_key > 0 
    other_result = SELECT something FROM foo2 WHERE key=foreign_key 
end 

कोड अगर कोई संबंधित शाखा करने की जरूरत है दूसरी तालिका में पंक्ति, लेकिन क्या यह एक एकल चयन कथन में बाएं जॉइन करके बेहतर नहीं किया जा सकता है? क्या मुझे कुछ प्रदर्शन लाभ याद आ रहा है? पोर्टेबिलिटी मुद्दा? या मैं बस नाइटपिक कर रहा हूँ?

+0

मैं 1987 के बाद से SQL डेटाबेस का उपयोग किया गया है, लेकिन मैं किसी भी एसक्यूएल पाठ्यक्रम ले लिया कभी नहीं किया है। काफी हाल ही में, शायद मैं इसे पहला तरीका कर सकता था क्योंकि मुझे अच्छी तरह से बाएं जॉइन नहीं पता था। –

+0

क्या यह _really_ नौ प्लस उत्तरों की आवश्यकता है? – Will

+2

@Will, क्या आपके पास उत्तर की अंगूठी में अपनी टोपी फेंकने वाले हर किसी के खिलाफ कुछ है? अधिक बेहतर जवाब देंगे, अच्छे लोग सतह पर होंगे। – mmcdole

उत्तर

5

वास्तव में प्रश्न का उत्तर देने के लिए पर्याप्त जानकारी नहीं है। मैंने उन अनुप्रयोगों पर काम किया है जहां एक कारण के लिए क्वेरी गिनती कम हो रही है और अन्य कारणों से क्वेरी गिनती दोनों ने प्रदर्शन सुधार दिए हैं। एक ही आवेदन में!

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

+0

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

+0

तथ्य यह है कि यह स्वीकार कर लिया गया मुझे रोना ... क्या तुमने कभी, बाद निष्कर्ष यह है कि स्वतंत्र चयन बेहतर हैं के लिए आते हैं तुरंत अपने डेटाबेस परमाणु क्योंकि यह अपना काम नहीं कर रहा है चाहता हूँ बनाता है। –

+0

और सभी लोग जवाब पोस्ट करते हैं और टिप्पणी करते हैं "यह 1 प्रश्न होना चाहिए!" स्पष्ट रूप से भूल गए हैं कि असली दुनिया मौजूद है। – staticsan

3

मैं तुम्हारे साथ हूँ - एक एकल एसक्यूएल बेहतर

2

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

एक ही कथन का एक लाभ - आपके पास सर्वर के लिए कम दौर की यात्रा है - खासकर यदि एसक्यूएल हर बार अन्य परिणाम की आवश्यकता होती है तो गतिशील रूप से तैयार की जाती है।

औसतन, एक एकल चयन कथन बेहतर होता है। यह ऑप्टिमाइज़र को कुछ करने देता है और इसे भी ऊब जाता है।

+0

हां, हमें अनुकूलक को खुश और पूरा रखना होगा! :-) –

2

मुझे ऐसा लगता है कि तुम क्या कह रहे हैं काफी वैध है - क्यों डेटाबेस के लिए दो कॉल बंद आग जब एक करना होगा - (?) जब तक दोनों रिकॉर्ड वस्तुओं के रूप में स्वतंत्र रूप से की जरूरत है

बेशक

जबकि यह शायद डेटाबेस से एक कॉल में इसे वापस खींचने के लिए सरल कोड के रूप में नहीं हो सकता है और फ़ील्ड को दो अलग-अलग ऑब्जेक्ट्स में अलग कर सकता है, इसका मतलब यह है कि आप केवल दो कॉल के बजाय डेटाबेस पर निर्भर हैं ...

Select a.blah1, a.blah2, b.something From foo a Left Join foo2 b On a.foreign_key = b.key Where a.Key = bar; 
:

यह एक प्रश्न के रूप में पढ़ने के लिए अच्छे होगा

और इस तरह आप जांच सकते हैं कि आपको एक बार में एक परिणाम मिला है और डेटाबेस दो भारी बजाय एक प्रश्न में भारी भारोत्तोलन कर रहा है ...

हाँ, मुझे लगता है कि ऐसा लगता है कि आप क्या कह रहे हैं सही बात।

6

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

+0

मेरी तालिका में 20 मिलियन प्रविष्टियां हैं और यह पता चला है कि इस तालिका में शामिल होने के बावजूद कई प्रश्नों के साथ 5s बनाम 1s था। राउंड ट्रिप समय। – velop

1

ध्यान में रखते हुए कि एक डेटाबेस में हिट होने पर आपके पास एक ही SQL कथन होगा, जिसमें 99% समय का बेहतर प्रदर्शन होगा। सुनिश्चित नहीं है कि कनेक्शन इस मामले में गतिशील रूप से बना रहे हैं या नहीं, लेकिन यदि ऐसा करना महंगा है। भले ही मौजूदा कनेक्शन का पुन: उपयोग करने की प्रक्रिया डीबीएमएस को अनुकूलन नहीं मिल रहा है, प्रश्नों का सबसे अच्छा तरीका है और वास्तव में रिश्तों का उपयोग नहीं कर रहा है।

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

1

इस सब के लिए एकमात्र "गोचाचा" यह है कि परिणाम के साथ काम करने के लिए सेट में बहुत सारे शामिल हैं, या यहां तक ​​कि घोंसला भी शामिल है।

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

मैं प्रक्रिया में वापस चला गया, कुछ तालिका चर (या अस्थायी तालिकाओं) का लाभ उठाया और क्वेरी को छोटे एकल चयन प्रकार के बयान में तोड़ दिया और इस तरह से अंतिम परिणाम सेट का निर्माण किया।

यह अद्यतन नाटकीय रूप से प्रतिक्रिया समय तय, कुछ सेकंड के लिए नीचे है क्योंकि यह आसान था सरल "एक शॉट" का एक बहुत करने के लिए आवश्यक डेटा पुनः प्राप्त करने।

मैं यहाँ आपत्तियों खातिर आपत्ति करने की कोशिश कर नहीं कर रहा हूँ, लेकिन सिर्फ करते रहे कि कोड हो सकता है एक ऐसी ही मुद्दे के समाधान के लिए इस तरह के एक बारीक स्तर के लिए टूट गया है।

+0

अच्छा बिंदु। और यह डेटाबेस इंजन में कमजोरी भी प्रकट नहीं करता है? प्रोग्रामर को ऐसे मजबूत SQL-fu होने की आवश्यकता नहीं है ... – zetetic

+1

मैं इसे डेटा इंजन में कमजोरी नहीं कहूंगा। कभी-कभी यह प्रोग्रामर में डेटाबेस की बेतुका चीजें पूछने में निहित है। –

2

सबसे अधिक संभावना स्पष्टीकरण यह है कि डेवलपर को यह नहीं पता कि बाहरी कैसे काम करता है। यह उन लोगों के बीच भी बहुत आम है, जो अपनी विशेषताओं में काफी अनुभवी हैं।

वहाँ भी एक व्यापक मिथक है कि है "मिलती है साथ प्रश्नों धीमी गति से कर रहे हैं।" इतने सारे डेवलपर अंधेरे से सभी लागतों में शामिल होने से बचते हैं, यहां तक ​​कि कई प्रश्नों को चलाने के चरम पर भी जहां कोई बेहतर होगा।

से बचने के मिथक मिलती कह हम, हमारे आवेदन कोड में छोरों लेखन से बचना चाहिए क्योंकि कोड की एक पंक्ति चल कई बार स्पष्ट रूप से यह एक बार चल रहा है की तुलना में धीमी है की तरह है। ++i के "ओवरहेड" के कुछ भी नहीं कहने और प्रत्येक पुनरावृत्ति के दौरान i<20 का परीक्षण करने के लिए!

+0

यह मेरा विचार भी था, लेकिन डेवलपर सिस्टम के अन्य हिस्सों में बाहरी जुड़ने का उपयोग करता है, इसलिए ऐसा नहीं है कि वह पूरी तरह से अज्ञानी था। पहले स्थान पर (मैं बच्चा! मैं बच्चा!) – zetetic

1

एक एकल SQL क्वेरी एसक्यूएल सर्वर (जो कभी कभी एक ही स्थान साझा नहीं करता है) के रूप में अधिक प्रदर्शन में नेतृत्व करेंगे सिर्फ एक अनुरोध को पूरा करने की जरूरत है, यदि आप कई एसक्यूएल प्रश्नों का प्रयोग करेंगे तो आप भूमि के ऊपर का एक बहुत परिचय:

अधिक CPU निर्देश निष्पादित, सर्वर के लिए एक दूसरा प्रश्न भेजने, सर्वर पर एक दूसरे धागा बनाने के लिए, , सर्वर पर अमल संभव अधिक CPU निर्देश सर्वर पर एक दूसरे धागा नष्ट, भेज दूसरे परिणाम पीछे।

असाधारण मामले हो सकते हैं जहां प्रदर्शन बेहतर हो सकता है, लेकिन साधारण चीजों के लिए आप थोड़ा और काम करके बेहतर प्रदर्शन तक नहीं पहुंच सकते हैं।

1

आमतौर पर इस समस्या डोमेन के बाद जाने का सबसे अच्छा तरीका है, हालांकि टेबल और इंडेक्सिंग की स्थिति के आधार पर, कुछ ऐसे मामले हैं जहां दो चयन कथन करना बेहतर हो सकता है, लेकिन जब तक मैं 3-5 में शामिल हो गए टेबल, आ शुरू कर दिया आम तौर पर मैं इस समस्या में पड़ नहीं किया है न सिर्फ 2.

बस सुनिश्चित करें कि आप दोनों तालिकाओं पर अनुक्रमणिका को कवर किया है सुनिश्चित करने के लिए आप सभी रिकॉर्ड के लिए डिस्क को स्कैन नहीं कर रहे हैं, कि सबसे बड़ा प्रदर्शन डेटाबेस (अपने सीमित अनुभव में) हो जाता है

2

आप पूरी तरह से सही है कि एक क्वेरी जाने का रास्ता है कर रहे हैं मारा है। प्रस्तावित अन्य उत्तरों में कुछ मूल्य जोड़ने के लिए मुझे यह सिद्धांत जोड़ने दें: "नौकरी के लिए सही उपकरण का उपयोग करें, डेटाबेस सर्वर को क्वेरीिंग कार्य को संभालना चाहिए, कोड को प्रक्रियात्मक कार्य को संभालना चाहिए।"

इस अवधारणा के पीछे विचार यह है कि कुंजी संकलक/क्वेरी अनुकूलक एक बेहतर काम कर सकता है अगर वे पूरे समस्या डोमेन के बजाय इसे के आधे पता है।

1

करते समय आपको हमेशा यह कर सकते हैं डेटाबेस के लिए क्वेरी की संख्या को कम करने के लिए प्रयास करना चाहिए। आपका उदाहरण केवल 1 क्वेरी के लिए बिल्कुल सही है। इस तरह आप बाद में अधिक आसानी से कैश करने में सक्षम होंगे या एक ही समय में अधिक अनुरोध को संभालने में सक्षम होंगे क्योंकि हमेशा एक कनेक्शन की आवश्यकता वाले 2-3 क्वेरी का उपयोग करने के बजाय, आपके पास प्रत्येक बार केवल 1 होगा।

1

कई मामलों है कि विभिन्न समाधान की आवश्यकता होगी रहे हैं और यह सब एक साथ व्याख्या करने के लिए संभव नहीं है।

स्कैन दोनों तालिकाओं में शामिल हों और दूसरी तालिका में पहले तालिका रिकॉर्ड से मिलान करने के लूप। सरल चयन क्वेरी कई मामलों में तेजी से काम करेगी क्योंकि यह आंतरिक रूप से डेटा खोजने के लिए केवल प्राथमिक/अद्वितीय कुंजी (यदि मौजूद है) की परवाह करता है।

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