2014-07-22 13 views
6

मेरे पास मोंगो डीबी में 600k से अधिक रिकॉर्ड हैं।प्रक्षेपण क्वेरी धीमी बनाता है

{ 
    "_id" : ObjectId, 
    "password" : String, 
    "email" : String, 
    "location" : Object, 
    "followers" : Array, 
    "following" : Array, 
    "dateCreated" : Number, 
    "loginCount" : Number, 
    "settings" : Object, 
    "roles" : Array, 
    "enabled" : Boolean, 
    "name" : Object 
} 

निम्न क्वेरी: इस में

db.users.find(
    {}, 
    { 
     name:1, 
     settings:1, 
     email:1, 
     location:1 
    } 
).skip(656784).limit(10).explain() 

परिणाम:

{ 
    "cursor" : "BasicCursor", 
    "isMultiKey" : false, 
    "n" : 10, 
    "nscannedObjects" : 656794, 
    "nscanned" : 656794, 
    "nscannedObjectsAllPlans" : 656794, 
    "nscannedAllPlans" : 656794, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 5131, 
    "nChunkSkips" : 0, 
    "millis" : 1106, 
    "server" : "shreyance:27017", 
    "filterSet" : false 
} 

और इस में प्रक्षेपण समान क्वेरी को हटाने db.users.find().skip(656784).limit(10).explain()

परिणाम के बाद मेरे उपयोगकर्ता स्कीमा इस तरह दिखता है :

{ 
    "cursor" : "BasicCursor", 
    "isMultiKey" : false, 
    "n" : 10, 
    "nscannedObjects" : 656794, 
    "nscanned" : 656794, 
    "nscannedObjectsAllPlans" : 656794, 
    "nscannedAllPlans" : 656794, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 5131, 
    "nChunkSkips" : 0, 
    "millis" : 209, 
    "server" : "shreyance:27017", 
    "filterSet" : false 
} 

जहाँ तक मुझे पता है कि प्रक्षेपण हमेशा एक क्वेरी के प्रदर्शन में वृद्धि करता है। तो मैं समझने में असमर्थ हूं कि मोंगोडीबी इस तरह क्यों व्यवहार कर रहा है। क्या कोई इसे समझा सकता है। और जब प्रक्षेपण का उपयोग करें और कब नहीं। और वास्तव में मोंगोडीबी में प्रक्षेपण कैसे लागू किया जाता है।

+1

क्या आप इन परिणामों को बार-बार प्राप्त करते हैं? दूसरी क्वेरी तेज हो सकती है क्योंकि पहली क्वेरी से डेटा कैश किया गया है (स्मृति में लोड किया गया है)। – Messa

+0

क्योंकि यह 656794 दस्तावेज़ – Sammaye

+0

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

उत्तर

4

आप सही हैं कि प्रोजेक्शन मोंगोडीबी 2.6.3 में इस स्किप क्वेरी को धीमा कर देता है। यह 2.6 क्वेरी प्लानर के साथ SERVER-13946 के रूप में ट्रैक किए गए अनुकूलन समस्या से संबंधित है।

2.6 क्वेरी प्लानर (2.6 के रूप में।3) प्रक्षेपण विश्लेषण के बाद SKIP (और LIMIT) चरणों को जोड़ रहा है, इसलिए प्रक्षेपण को इस क्वेरी के लिए छोड़ने के दौरान बाहर निकलने वाले परिणामों पर अनावश्यक रूप से लागू किया जा रहा है। मैंने MongoDB 2.4.10 में एक समान क्वेरी का परीक्षण किया और nScannedObjectsskip + limit के बजाय मेरे limit द्वारा दिए गए परिणामों की संख्या के बराबर था।

कई आपकी क्वेरी प्रदर्शन करने के लिए योगदान कारक हैं:

1) आप किसी भी क्वेरी मापदंड ({}) निर्दिष्ट नहीं किया है, तो यह क्वेरी natural order में एक संग्रह स्कैन कर रहा है के बजाय एक सूचकांक का उपयोग कर।

2) क्वेरी को कवर नहीं किया जा सकता है क्योंकि कोई प्रक्षेपण नहीं है।

3) आपके पास 656,784 का मूल्य बहुत बड़ा skip है।

निश्चित रूप से क्वेरी प्लान में सुधार के लिए जगह है, लेकिन मैं उम्मीद नहीं करता कि इस परिमाण के मूल्यों को सामान्य उपयोग में उचित माना जाए। उदाहरण के लिए, यदि यह प्रति पृष्ठ 50 परिणामों के साथ पृष्ठांकन के लिए एक आवेदन क्वेरी थी, तो skip() मान पृष्ठ संख्या 13,135 के बराबर होगा।

+1

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

1

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

आप प्रक्रिया पर विचार करने के लिए है:

  1. मैं कैसे मेल खाते हैं? दस्तावेज़ या सूचकांक पर? उपयुक्त प्राथमिक या अन्य सूचकांक खोजें।

  2. इंडेक्स को देखते हुए, स्कैन करें और चीजें खोजें।

  3. अब मुझे वापस क्या करना है? सूचकांक में डेटा के सभी है? यदि संग्रह पर वापस न जाएं और दस्तावेजों को खींचें।

बुनियादी प्रक्रिया है। तो जब तक कि उन चरणों में से कोई भी किसी भी तरीके से "अनुकूलित" नहीं करता है तो निश्चित रूप से चीजें "अधिक समय लेती हैं"।

आपको इसे "सर्वर इंजन" डिजाइन करने और उन कदमों को समझने की आवश्यकता है जिन्हें करने की आवश्यकता है। आपकी किसी भी स्थिति को ध्यान में रखते हुए कुछ भी नहीं मिला जो निर्दिष्ट चरणों पर "इष्टतम" उत्पन्न करेगा जिसे आपको स्वीकार करने के लिए सीखना होगा।

आपका "सर्वश्रेष्ठ" मामला, केवल अनुमानित फ़ील्ड चयनित इंडेक्स में मौजूद फ़ील्ड हैं। लेकिन वास्तव में, यहां तक ​​कि सूचकांक लोड करने का ओवरहेड भी है।

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

+2

के समान परिणाम मुझे नहीं लगता कि यह बताता है कि क्यों मोंगोडीबी ऐसा लगता है कि 656784 दस्तावेजों के लिए प्रक्षेपण कर रहा है, यह एक _id इंडेक्स – Sammaye

+1

@NeilLunn के साथ गिन सकता है, मैं आपकी बात समझ गया। लेकिन मैं सममय के साथ भी सहमत हूं कि 'मोंगो हर दस्तावेज के लिए प्रक्षेपण क्यों लागू कर रहा है' इसे केवल दस्तावेजों को वापस करने के लिए प्रक्षेपण लागू करना चाहिए –

+0

@ श्रेयेंसजैन ** ** ** ** प्रक्षेपण वास्तव में "प्रक्षेपण" के संदर्भ में यह कहां है कि यह " सूचकांक केवल "और इसलिए इंडेक्स में फ़ील्ड से" पिकिंग "को वास्तव में समेकन फ्रेमवर्क पाइपलाइन से '$ प्रोजेक्ट' ऑपरेटर की समझ की आवश्यकता होती है और क्वेरी इंजन प्रसंस्करण को समझना पड़ता है। अनिवार्य रूप से आप अन्यथा अपने सभी दस्तावेज़ों को "पास" करने और "पुनः आकार" करने के लिए कह रहे हैं। क्या इसे और स्पष्टीकरण की आवश्यकता है? –

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