कोड में "बहुत अधिक डेटाबेस अनुरोधों" को क्या योग्य है?


17

यह अपने आप में एक चर्चा है और मेरे कुछ सहयोगियों ने सोचा है और मैं यहां आकर देखूंगा कि अगर इस पर आम सहमति है तो क्या होगा।

यह मूल रूप से डेटाबेस कॉल पर निम्नलिखित 2 राय के लिए नीचे आता है: 1. डेटाबेस को डीबी कॉल की संख्या को कम करने के लिए आवश्यक सब कुछ प्राप्त करने के लिए एक बड़ी कॉल करें 2. जो आकार का आकार कम करने के लिए अनुरोध किया गया है, उसके आधार पर छोटी अलग कॉल करें DB कॉल करता है

जहां यह विशेष रूप से खेल में आ रहा है आम कोड में है। हम एक कर्मचारी वर्ग के उदाहरण का उपयोग करेंगे क्योंकि यह काफी सीधा है।

मान लीजिए कि आपके कर्मचारी वर्ग में 10 मान विशेषताएँ (पहला नाम, अंतिम नाम, काम पर रखा गया है, आदि) और फिर 2 वर्ग गुण हैं ... 1 विभाग वर्ग की ओर इशारा करता है और फिर 1 पर्यवेक्षक जो किसी अन्य कर्मचारी ऑब्जेक्ट पर वापस इंगित करता है।

# 1 मानसिकता में, आप एक कॉल करते हैं जो कर्मचारी डेटा के साथ-साथ विभाग और पर्यवेक्षक विशेषताओं को पॉप्युलेट करने के लिए आवश्यक फ़ील्ड ... या कम से कम उन फ़ील्ड्स का उपयोग करता है जो उन सब ऑब्जेक्ट्स से अक्सर उपयोग किए जाते हैं।

# 2 मानसिकता में, आप केवल पहली बार में कर्मचारी की वस्तु को पॉप्युलेट करेंगे और उसके बाद ही विभाग और पर्यवेक्षक की वस्तुओं को पॉप्युलेट करेंगे, यदि वे वास्तव में अनुरोधित हैं।

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

इस पर शोध करने के पीछे प्रेरक शक्ति यह है कि हमारे वेबसर्वर और डेटाबेस सर्वर के बीच यातायात की मात्रा नियंत्रण से बाहर हो रही है।


7
मेरे अनुभव में इसके लिए "सही उत्तर" नहीं है। विलंबता और थ्रूपुट के बीच संतुलन है। कम विलंबता बहुत सारे अनुरोधों या यहां तक ​​कि एक बड़े को सहन कर सकती है; हालाँकि, उच्च विलंबता लिंक एक साथ बहुत सारे डेटा को स्थानांतरित करने से बेहतर होते हैं। फिर भी, यदि एक उच्च विलंबता कॉन्फ़िगरेशन में थ्रूपुट कम है, तो आप अधिक संवेदनशील होने के लिए छोटे विखंडू प्राप्त करने से बेहतर हैं।

3
संभवतः n + 1 समस्या से संबंधित है stackoverflow.com/questions/97197/…
वलेरा कोलुपाव

@Valera: सुविधा यहाँ लिंक है कि प्रश्न पर तैनात है: realsolve.co.uk/site/tech/hib-tip-pitfall.php?name=n1selects
rwong

4
"हमारे वेबसर्वर और डेटाबेस सर्वर के बीच यातायात की मात्रा नियंत्रण से बाहर हो रही है।" इसका क्या मतलब है? क्या आप इस बात पर विशिष्ट हो सकते हैं कि वास्तविक समस्या क्या है? क्या आपको प्रदर्शन समस्याएं हैं? क्या आपने प्रोफाइलिंग और माप किया है? कृपया प्रश्न के भाग के रूप में वास्तविक माप से वास्तविक परिणाम प्रदान करें। अन्यथा, हम सिर्फ अनुमान लगा रहे हैं।
S.Lott

जवाबों:


8

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

आप किस भाषा और फ्रेमवर्क का उपयोग कर रहे हैं, उसके आधार पर, पहले से ही एक कैशिंग ढांचा हो सकता है जो आपकी आवश्यकता के कुछ (या अधिकांश) कर सकता है। यदि आप जावा का उपयोग करते हैं, तो आप अपाचे कॉमन्स-कैश में देख सकते हैं (मैंने इसे कुछ समय के लिए उपयोग नहीं किया है, और जब यह निष्क्रिय दिखता है, तो यह अभी भी उपयोग करने के लिए उपलब्ध है और पिछली बार जब मैंने इसका उपयोग किया था तो यह बहुत ही सभ्य था)।


3

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

के रूप में भी कई के रूप में वर्गीकृत करता है, कि आवेदन पर निर्भर करता है। अधिकांश वेब अनुप्रयोगों के लिए 30 सेकंड से कम कुछ भी स्वीकार्य है। मैं आपके उपयोगकर्ताओं से उनकी अपेक्षाओं के अनुसार बोलूंगा।


एक बुरी तरह से लिखित डीबी कॉल का गठन क्या है?
nu सदाबहार

3

आपका प्रश्न इस धारणा पर आधारित है कि आपको यह अनुमान लगाना है कि किसी भी पृष्ठ के लिए कौन से डेटा की आवश्यकता होगी। ऐसी बात नहीं है। यह भोली दृष्टिकोण जितना आसान नहीं है, लेकिन आप अपने कोड को आर्किटेक्ट कर सकते हैं ताकि आपको पता चल जाएगा कि क्या आपको किसी भी डेटाबेस कॉल करने से पहले विभाग या पर्यवेक्षक विशेषताओं की आवश्यकता है।


3

ये मेरे द्वारा उपयोग किए जाने वाले नियम हैं, हो सकता है कि वे आपके उपयोग के हों।

  1. पहले उपाय! मैं उस कोड को भी नहीं देखूंगा जो "धीमा हो सकता है" जब तक मैं वास्तव में उस संसाधन के लिए ट्रैफ़िक नहीं देख सकता हूं और वह संसाधन धीरे-धीरे प्रतिक्रिया दे रहा है।
  2. 1 अनुरोध = K प्रश्न। डेटाबेस से बात करने की संख्या पूरी तरह से अनुरोध किए गए संसाधन के प्रकार से निर्धारित होती है; और उस संसाधन के अनुरोध या स्थिति की प्रकृति से कभी नहीं; आपके उदाहरण में, यह संभवतः 3 प्रश्नों पर है: कर्मचारियों के लिए 1, विभागों के लिए 1 और पर्यवेक्षकों के लिए 1; इससे कोई फर्क नहीं पड़ता कि प्रत्येक के कितने होने की संभावना है।
  3. क्या आप उपयोग नहीं करेंगे क्वेरी मत करो । अगर यह HTTP है जिसके बारे में हम बात कर रहे हैं, तो बाद में डेटा को क्वेरी करने में कोई मतलब नहीं है; बाद में नहीं है; प्रत्येक अनुरोध एक साफ स्लेट से शुरू होता है। कभी-कभी मुझे मेज से अधिकांश स्तंभों की आवश्यकता होती है , लेकिन अवसर पर मुझे केवल एक या दो की आवश्यकता होती है; जब मुझे ठीक-ठीक फ़ील्ड्स की ज़रूरत होती है, तो मैं बस उसी के लिए कहूँगा।
  4. समस्या पर हार्डवेयर फेंको। नौकर सस्ते होते हैं; कभी-कभी आप डेटाबेस को बीफ़ियर बॉक्स में ले जाकर पर्याप्त प्रदर्शन प्राप्त कर सकते हैं; या कुछ प्रश्नों को केवल-पढ़ने के लिए प्रतिकृति भेज रहा है।
  5. पहले कैश को अमान्य करें, फिर कैशिंग लागू करें। कैश में डेटा को क्वेरी करने के लिए अक्सर उपयोग किए जाने वाले या कठिन डालने का आग्रह मजबूत है; लेकिन सभी-अक्सर, अप्रयुक्त डेटा को बेदखल करने या सुपरसीड डेटा को समाप्त करने की अनदेखी की जाती है। यदि आप जानते हैं कि कैश से डेटा कैसे निकालना है; तब आप इसे कैश में सुरक्षित रख रहे हैं; यदि यह कैश को अमान्य करने की तुलना में अधिक महंगा हो जाता है तो केवल क्वेरी करने के लिए; तब आपको कैश की आवश्यकता नहीं थी।

2

यहां की दोनों रणनीतियाँ पूरी तरह से मान्य हैं। प्रत्येक के फायदे और नुकसान हैं:

सभी 3 वस्तुओं के लिए एक कॉल:

  • तेजी से प्रदर्शन करेंगे
  • आपको वही मिलेगा जो आपको उस मामले में चाहिए जहां आपको इसकी आवश्यकता है
  • शायद केवल एक मामले में प्रयोग करने योग्य होगा (यह एक बहुत ही सामान्य मामला हो सकता है)
  • बनाए रखना अधिक कठिन होगा
  • अधिक बार बनाए रखना होगा (क्योंकि यह 3 वस्तुओं के स्कीमा या आवश्यक डेटा परिवर्तन में से कोई भी बदल जाएगा)

ऑब्जेक्ट प्रति एक कॉल (कुल 3 कॉल)

  • आपको प्रत्येक वस्तु प्रकार के एकल उदाहरण को पॉप्युलेट करने के लिए एक सामान्य-उद्देश्य कॉल देता है; वे तो स्वतंत्र रूप से इस्तेमाल किया जा सकता है
  • अधिक टिकाऊ होगा क्योंकि क्वेरी संरचना सरल होगी।
  • धीमी होगी (जरूरी नहीं कि 3 बार धीमी गति से हो, लेकिन एक ही डेटा के लिए ओवरहेड बढ़ जाता है)
  • अनावश्यक डेटा प्राप्त करने के साथ समस्याएँ पैदा कर सकते हैं (पूरे रिकॉर्ड को खींचना जब आपको एक फ़ील्ड बेकार है)
  • हो सकता है कि N-1 समस्याएँ तब होती हैं जब एक-से-एक संबंध मौजूद होता है, अगर एकल-रिकॉर्ड क्वेरी को N बार, संग्रह में प्रति रिकॉर्ड एक बार भेजा जाता है।

आपकी चिंताओं के एक जोड़े के जवाब में (# 3 और 5 दूसरी सूची में) ... क्या होगा यदि पर्यवेक्षक और विभाग केवल 1/3 (या कम) का उपयोग करते हैं? क्या होगा यदि कोड को सभी बच्चों को सूची के रूप में जल्द से जल्द डिजाइन किया गया था <> ऑब्जेक्ट कोड करने के लिए उन्हें पहले संदर्भित किया गया था? ... इससे सबसे ज्यादा सुकून मिलेगा?
user107775

यदि सहायक वस्तुओं की केवल शायद ही कभी जरूरत होती है, तो सामान्य स्थिति में यह तेजी से (कम डेटा प्राप्त करने के लिए) प्रदर्शन करेगा लेकिन सबसे खराब स्थिति धीमी (समान डेटा या अधिक पुनर्प्राप्त की जाएगी, आपके कंप्यूटर से तीन गुना संचार ओवरहेड का उपयोग करके) होगी। N + 1 समस्या के लिए, आपको बस उस क्वेरी को आर्किटेक्ट करने में सक्षम होना चाहिए जो वस्तुओं की एक सूची को पुनः प्राप्त करने में सक्षम हो, ताकि रिश्ते की "एक" तरफ विदेशी कुंजी के आधार पर ऐसा किया जा सके, और फिर कई पंक्तियों को खींच सकें क्वेरी परिणाम से बाहर। आप उस क्वेरी के किसी संस्करण का उपयोग नहीं कर सकते जिसके पास रिकॉर्ड की प्राथमिक कुंजी है।
कीथ्स

1

मेरे लिए, बहुत अधिक DB अनुरोध किसी भी समय आपके द्वारा आवश्यक डेटा लोड करने की आवश्यकता से अधिक अनुरोध कर रहे हैं।

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

इसलिए दोनों विकल्प हैं, और हर एक का उपयोग करें जहां स्थिति इसके लिए कॉल करती है।

EDIT: ध्यान रखें कि यह संभोग आपकी स्थिति पर भी निर्भर करता है। यदि उदाहरण के लिए इसका एक वेबएप है तो आपके पास अलग-अलग विचार होने चाहिए जैसे कि एक डेस्कटॉप ऐप आपके नेटवर्क के भीतर डीबी तक पहुंचता है, जैसा कि वीपीएपी के लिए पूरे वेब पर है।


उस घटना के बारे में जो आप सामान्य कोड लिख रहे हैं और आप निश्चित नहीं हैं कि आपके कोड का उपयोग किस तरीके से किया जाएगा। हो सकता है कि आप कभी किसी को पर्यवेक्षक की आवश्यकता के बारे में कल्पना नहीं करेंगे, लेकिन यह पता चला है कि जिस एप्लिकेशन पर आप काम करते हैं, वह केवल उसी की आवश्यकता है। ज़रूर, आप अलग-अलग फ़ंक्शन लिख सकते हैं ... एक इसे शामिल करने के लिए और दूसरा इसे शामिल करने के लिए लेकिन किस बिंदु पर आपका सामान्य कोड उपयोग करने के लिए बहुत विस्तृत ज्ञान की आवश्यकता शुरू करता है?
15:10 बजे user107775

@ user107775 मैं आमतौर पर प्रत्येक मामले के लिए केवल दो फ़ंक्शन लिखता हूं; एक जो केवल संपत्ति मूल्यों को लौटाता है, और एक वह जो सभी संबंधित वर्गों के साथ वर्ग को लौटाता है। ऐसा इसलिए है क्योंकि MOST बार, आपको केवल संपत्तियों की आवश्यकता है। इस तरह, आपको विस्तृत ज्ञान की आवश्यकता नहीं है, बस एक मूल बातें और दूसरी सब कुछ प्राप्त करें। मुझे यह एक उचित संतुलन लगता है। (हालाँकि कुछ जासूसी के मामले अधिक अनुकूलन के लिए कहते हैं, लेकिन यह केस के आधार पर होता है)।
एजेसी

1

डीबी से कनेक्ट करें, अनुरोध भेजें और इसे प्राप्त करें, परिणाम प्राप्त करने की तुलना में आमतौर पर महत्वपूर्ण समय लगता है, इसलिए समग्र प्रवृत्ति एक अनुरोध में अधिक से अधिक प्रश्नों को संक्षिप्त करना है।

फिर भी, एक शॉट में यह सब करने से कोड अप्राप्य हो जाएगा। इसके बजाय, यह आमतौर पर एक अतिरिक्त अमूर्त परत द्वारा प्राप्त किया जाता है: कोड कई अनुरोधों को शेड्यूल करता है जैसे कि उन्हें आवश्यकता होती है, फिर इंजन इसे एक बड़े अनुरोध के रूप में पार्स करता है (संभवतः रास्ते में कैश का उपयोग करके) और फिर उत्तरों को आवश्यकतानुसार भेज दिया जाता है।

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

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


1

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

यह जानना दिलचस्प होगा कि यह कितना डीबी मेमोरी बनाम डिस्क से आ रहा है। मुझे यह महसूस करने के लिए कुछ भी नहीं है कि पते की तुलना में विभाग कम या ज्यादा बदल सकता है।

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