MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

5 मिलियन से अधिक रिकॉर्ड के लिए MongoDB क्वेरी प्रदर्शन

यह भूसे के ढेर में सुई खोज रहा है। हमें कुछ आउटपुट की आवश्यकता होगी explain() उन प्रश्नों के लिए जो अच्छा प्रदर्शन नहीं करते हैं। दुर्भाग्य से, यह भी केवल उस विशेष क्वेरी के लिए समस्या को ठीक करेगा, इसलिए यहां एक रणनीति है कि इसे कैसे प्राप्त किया जाए:

  1. सुनिश्चित करें कि यह अपर्याप्त RAM और अत्यधिक पेजिंग के कारण नहीं है
  2. DB प्रोफाइलर सक्षम करें (db.setProfilingLevel(1, timeout) का उपयोग करके) जहां समयबाह्य क्वेरी या कमांड में लगने वाले मिलीसेकंड की संख्या के लिए दहलीज है, कुछ भी धीमा लॉग किया जाएगा)
  3. धीमे प्रश्नों की जांच db.system.profile . में करें और explain() . का उपयोग करके मैन्युअल रूप से प्रश्नों को चलाएं
  4. धीमे संचालन की पहचान करने का प्रयास करें explain() आउटपुट, जैसे scanAndOrder या बड़ा nscanned , आदि.
  5. क्वेरी की चयनात्मकता के कारण और क्या किसी इंडेक्स का उपयोग करके क्वेरी में सुधार करना संभव है बिल्कुल . यदि नहीं, तो अंतिम-उपयोगकर्ता के लिए फ़िल्टर सेटिंग को अस्वीकार करने पर विचार करें या उसे एक चेतावनी संवाद दें कि कार्रवाई धीमी हो सकती है।

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

साथ ही, प्रत्येक संभावित क्वेरी पर एक इंडेक्स को आँख बंद करके फेंकना एक बहुत ही खराब रणनीति है। प्रश्नों की संरचना करना और यह सुनिश्चित करना महत्वपूर्ण है कि अनुक्रमित फ़ील्ड में पर्याप्त चयनात्मकता . है .

मान लें कि आपके पास स्थिति . वाले सभी उपयोगकर्ताओं के लिए एक क्वेरी है "सक्रिय" और कुछ अन्य मानदंड। लेकिन 5 मिलियन उपयोगकर्ताओं में से 3 मिलियन सक्रिय हैं और 2 मिलियन नहीं हैं, इसलिए 5 मिलियन से अधिक प्रविष्टियां केवल दो अलग-अलग मान हैं। ऐसा सूचकांक आमतौर पर मदद नहीं करता है। पहले अन्य मानदंडों को खोजना बेहतर है, फिर परिणामों को स्कैन करें। औसतन, 100 दस्तावेज़ लौटाते समय, आपको 167 दस्तावेज़ों को स्कैन करना होगा, जो प्रदर्शन को बहुत बुरी तरह प्रभावित नहीं करेगा। लेकिन यह इतना आसान नहीं है। यदि प्राथमिक मानदंड join_at . है उपयोगकर्ता की तिथि और समय के साथ उपयोगकर्ताओं द्वारा उपयोग बंद करने की संभावना अधिक है, आपको हजारों स्कैन करने पड़ सकते हैं सौ मैचों को खोजने से पहले दस्तावेजों की।

इसलिए अनुकूलन डेटा पर बहुत अधिक निर्भर करता है (न केवल इसकी संरचना , लेकिन साथ ही डेटा स्वयं ), इसके आंतरिक सहसंबंध और आपके क्वेरी पैटर्न

जब रैम के लिए डेटा बहुत बड़ा होता है तो चीजें और भी खराब हो जाती हैं, क्योंकि तब, एक इंडेक्स होना बहुत अच्छा होता है, लेकिन परिणामों को स्कैन करने (या यहां तक ​​कि वापस लौटने) के लिए डिस्क से बहुत सारे डेटा को बेतरतीब ढंग से लाने की आवश्यकता हो सकती है जिसमें बहुत समय लगता है।

इसे नियंत्रित करने का सबसे अच्छा तरीका विभिन्न प्रकार की क्वेरी की संख्या को सीमित करना, कम चयनात्मकता जानकारी पर प्रश्नों को अस्वीकार करना और पुराने डेटा तक यादृच्छिक पहुंच को रोकने का प्रयास करना है।

यदि अन्य सभी विफल हो जाते हैं और यदि आपको वास्तव में फ़िल्टर में अधिक लचीलेपन की आवश्यकता है, तो एक अलग खोज डीबी पर विचार करना सार्थक हो सकता है जो इंडेक्स चौराहों का समर्थन करता है, वहां से मोंगो आईडी प्राप्त करता है और फिर $in<का उपयोग करके मोंगो से परिणाम प्राप्त करता है। /कोड> . लेकिन यह अपने ही खतरों से भरा है।

-- संपादित करें --

आपके द्वारा पोस्ट की गई व्याख्या कम चयनात्मकता वाले क्षेत्रों को स्कैन करने में समस्या का एक सुंदर उदाहरण है। जाहिर है, "[email protected]" के लिए बहुत सारे दस्तावेज़ हैं। अब, उन दस्तावेज़ों को ढूंढना और उन्हें टाइमस्टैम्प द्वारा अवरोही क्रमबद्ध करना बहुत तेज़ है, क्योंकि यह उच्च-चयनात्मकता अनुक्रमणिका द्वारा समर्थित है। दुर्भाग्य से, चूंकि केवल दो प्रकार के उपकरण होते हैं, mongo को 'मोबाइल' से मेल खाने वाला पहला दस्तावेज़ खोजने के लिए 30060 दस्तावेज़ों को स्कैन करने की आवश्यकता होती है।

मुझे लगता है कि यह किसी प्रकार की वेब ट्रैकिंग है, और उपयोगकर्ता का उपयोग पैटर्न क्वेरी को धीमा कर देता है (क्या वह दैनिक आधार पर मोबाइल और वेब स्विच करेगा, क्वेरी तेज़ होगी)।

इस विशेष क्वेरी को तेजी से बनाने के लिए एक कंपाउंड इंडेक्स का उपयोग किया जा सकता है जिसमें डिवाइस प्रकार होता है, उदा।

. का उपयोग करना
a) ensureIndex({'username': 1, 'userAgent.deviceType' : 1, 'timestamp' :-1})

या

b) ensureIndex({'userAgent.deviceType' : 1, 'username' : 1, 'timestamp' :-1})

दुर्भाग्य से, इसका मतलब है कि find({"username" :"foo"}).sort({"timestamp" :-1}); जैसी क्वेरीज़ अब उसी अनुक्रमणिका का उपयोग नहीं कर सकते हैं, इसलिए, जैसा कि वर्णित है, अनुक्रमणिका की संख्या बहुत तेज़ी से बढ़ेगी।

मुझे डर है कि इस समय मोंगोडब का उपयोग करके इसके लिए कोई बहुत अच्छा समाधान नहीं है।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. mongoDB स्थापित करें (बाल प्रक्रिया विफल, त्रुटि संख्या 100 से बाहर निकली)

  2. Node.js में सबसे अच्छा RESTful API कैसे बनाएं?

  3. MongoDB से विश्वसनीय रूप से पुनः कनेक्ट करें

  4. उच्च उपलब्धता के लिए ओपन edX MongoDB डेटाबेस कैसे परिनियोजित करें

  5. मोंगोडीबी एसक्यूएल इंजेक्शन गड़बड़ी से कैसे बचता है?