2015-03-17 12 views
6

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

मैंने खोज की और मेरी समस्या के लिए कोई समाधान नहीं मिला है, और मैं क्षमा चाहता हूं, क्योंकि मैं मोंगोडीबी के लिए काफी नया हूं और इस समय अपने बालों को खींच रहा हूं।

मैंगो डीबी का संस्करण मैं 2.4 एमबी का उपयोग कर रहा हूं, वीएम मशीन पर 20 जीबी रैम के साथ, जो उबंटू सर्वर 12.04 चलाता है। कोई प्रतिकृति या शेडिंग सेट अप नहीं है।

सबसे पहले, मैं 2 करने के लिए अपने रूपरेखा स्तर सेट और यह सबसे धीमी क्वेरी का पता चला:

db.system.profile.find().sort({"millis":-1}).limit(1).pretty() 
{ 
     "op" : "query", 
     "ns" : "station.measurement", 
     "query" : { 
       "$query" : { 
         "e" : { 
           "$gte" : 0 
         }, 
         "id" : "180" 
       }, 
       "$orderby" : { 
         "t" : -1 
       } 
     }, 
     "ntoreturn" : 1, 
     "ntoskip" : 0, 
     "nscanned" : 3295221, 
     "keyUpdates" : 0, 
     "numYield" : 6, 
     "lockStats" : { 
       "timeLockedMicros" : { 
         "r" : NumberLong(12184722), 
         "w" : NumberLong(0) 
       }, 
       "timeAcquiringMicros" : { 
         "r" : NumberLong(5636351), 
         "w" : NumberLong(5) 
       } 
     }, 
     "nreturned" : 0, 
     "responseLength" : 20, 
     "millis" : 6549, 
     "ts" : ISODate("2015-03-16T08:57:07.772Z"), 
     "client" : "127.0.0.1", 
     "allUsers" : [ ], 
     "user" : "" 
} 

मैं .explain() के साथ कि विशिष्ट क्वेरी भाग गया और की तरह लग रहा है, यह एकदम सही ढंग से सूचकांक का उपयोग करता है, लेकिन यह बहुत लंबा समय लेता है। मैंने अपने दूसरे, भारी कमजोर सर्वर पर भी यही प्रश्न चलाया और एक सेकंड में एक चैंप की तरह परिणाम निकाल दिया।

> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain() 
{ 
     "cursor" : "BtreeCursor id_1_t_-1_e_1", 
     "isMultiKey" : false, 
     "n" : 0, 
     "nscannedObjects" : 0, 
     "nscanned" : 660385, 
     "nscannedObjectsAllPlans" : 1981098, 
     "nscannedAllPlans" : 3301849, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 7, 
     "nChunkSkips" : 0, 
     "millis" : 7243, 
     "indexBounds" : { 
       "id" : [ 
         [ 
           "180", 
           "180" 
         ] 
       ], 
       "t" : [ 
         [ 
           { 
             "$maxElement" : 1 
           }, 
           { 
             "$minElement" : 1 
           } 
         ] 
       ], 
       "e" : [ 
         [ 
           0, 
           1.7976931348623157e+308 
         ] 
       ] 
     }, 
     "server" : "station:27017" 
} 

इसके बाद, मैं माप संग्रह की अनुक्रमणिका में देखा है और यह मेरे लिए ठीक लग रहा था:

> db.measurement.stats() 
{ 
     "ns" : "station.measurement", 
     "count" : 157835456, 
     "size" : 22377799512, 
     "avgObjSize" : 141.77929395027692, 
     "storageSize" : 26476834672, 
     "numExtents" : 33, 
     "nindexes" : 5, 
     "lastExtentSize" : 2146426864, 
     "paddingFactor" : 1.0000000000028617, 
     "systemFlags" : 0, 
     "userFlags" : 0, 
     "totalIndexSize" : 30996614096, 
     "indexSizes" : { 
       "_id_" : 6104250656, 
       "t_1" : 3971369360, 
       "id_1_d_1__id_-1" : 8397896640, 
       "id_1_t_-1_e_1" : 6261548720, 
       "id_1_t_-1_e_-1" : 6261548720 
     }, 
     "ok" : 1 
} 

:

> db.measurement.getIndexes() 
[ 
     { 
       "v" : 1, 
       "key" : { 
         "_id" : 1 
       }, 
       "ns" : "station.measurement", 
       "name" : "_id_" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "t" : 1 
       }, 
       "ns" : "station.measurement", 
       "name" : "t_1" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "id" : 1, 
         "d" : 1, 
         "_id" : -1 
       }, 
       "ns" : "station.measurement", 
       "name" : "id_1_d_1__id_-1" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "id" : 1, 
         "t" : -1, 
         "e" : 1 
       }, 
       "ns" : "station.measurement", 
       "name" : "id_1_t_-1_e_1" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "id" : 1, 
         "t" : -1, 
         "e" : -1 
       }, 
       "ns" : "station.measurement", 
       "name" : "id_1_t_-1_e_-1" 
     } 
] 

यहाँ भी मेरे संग्रह की जानकारी के बाकी है मैंने नई अनुक्रमणिका जोड़ने, पूरे डेटाबेस की मरम्मत, reindex की कोशिश की। मैं क्या गलत कर रहा हूं? मैं वास्तव में किसी भी मदद की सराहना करता हूं क्योंकि मैं विचारों से बेहद दूर भाग गया था।

अद्यतन 1: दिलचस्प (यकीन है कि नहीं कर रहे हैं

{ 
       "v" : 1, 
       "key" : { 
         "id" : 1, 
         "e" : 1, 
         "t" : -1 
       }, 
       "ns" : "station.measurement", 
       "name" : "id_1_e_1_t_-1", 
       "background" : true 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "id" : 1, 
         "e" : -1, 
         "t" : -1 
       }, 
       "ns" : "station.measurement", 
       "name" : "id_1_e_-1_t_-1", 
       "background" : true 
     } 

परिणाम मुझे मिल गया है, हालांकि:

मैं के रूप में नील लुन ने सुझाव दिया इंडेक्स जोड़ा, प्रश्नों में से कुछ एक बहुत तेजी से कर रहे हैं वे प्रासंगिक हैं)

अगले दो प्रश्न केवल "आईडी" से अलग हैं। कृपया ध्यान दें, प्रत्येक क्वेरी अलग-अलग इंडेक्स का उपयोग करती है, क्यों? क्या मुझे पुराने लोगों को हटा देना चाहिए?

> db.measurement.find({"id":"119", "e":{$gte:0}}).sort({"t":-1}).explain() 
{ 
     "cursor" : "BtreeCursor id_1_t_-1_e_1", 
     "isMultiKey" : false, 
     "n" : 840747, 
     "nscannedObjects" : 840747, 
     "nscanned" : 1047044, 
     "nscannedObjectsAllPlans" : 1056722, 
     "nscannedAllPlans" : 1311344, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 4, 
     "nChunkSkips" : 0, 
     "millis" : 3730, 
     "indexBounds" : { 
       "id" : [ 
         [ 
           "119", 
           "119" 
         ] 
       ], 
       "t" : [ 
         [ 
           { 
             "$maxElement" : 1 
           }, 
           { 
             "$minElement" : 1 
           } 
         ] 
       ], 
       "e" : [ 
         [ 
           0, 
           1.7976931348623157e+308 
         ] 
       ] 
     }, 
     "server" : "station:27017" 
} 

> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain() 
{ 
     "cursor" : "BtreeCursor id_1_e_1_t_-1", 
     "isMultiKey" : false, 
     "n" : 0, 
     "nscannedObjects" : 0, 
     "nscanned" : 0, 
     "nscannedObjectsAllPlans" : 0, 
     "nscannedAllPlans" : 45, 
     "scanAndOrder" : true, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 0, 
     "indexBounds" : { 
       "id" : [ 
         [ 
           "180", 
           "180" 
         ] 
       ], 
       "e" : [ 
         [ 
           0, 
           1.7976931348623157e+308 
         ] 
       ], 
       "t" : [ 
         [ 
           { 
             "$maxElement" : 1 
           }, 
           { 
             "$minElement" : 1 
           } 
         ] 
       ] 
     }, 
     "server" : "station:27017" 
} 

क्या समस्या कहीं और हो सकती है? अचानक "आलसीपन" का कारण क्या हो सकता है? मेरे पास कई अन्य संग्रह हैं, जहां प्रश्न अचानक धीमे होते हैं।

ओह, और एक और बात। मेरे पास उस अन्य सर्वर पर, नए जोड़े जोड़े जाने से पहले इंडेक्स समान हैं। हां, संग्रह थोड़ा छोटा है लेकिन यह कई गुना तेज है।

+2

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

+0

दिलचस्प सुझाव, धन्यवाद! मैं नई अनुक्रमणिका (id_1_e_1_t_-1 और id_1_e_-1_t_-1) जोड़ूंगा और आपको जल्द ही परिणामों के बारे में बता दूंगा क्योंकि इंडेक्स बनाने में कुछ समय लगेगा। – Denis

+0

अरे, मैंने सफलतापूर्वक उन इंडेक्स का निर्माण किया और कुछ प्रश्नों के साथ उनका परीक्षण किया। मैंने परिणामों के साथ अपना प्रश्न अपडेट किया :) – Denis

उत्तर

0

फिर यहां इंगित करें कि इंडेक्स और क्वेरी ऑर्डरिंग चयन दोनों में था।

यदि आप .explain() से अपने पहले के आउटपुट को देखते हैं तो आप देखेंगे कि आपकी अभिव्यक्ति में "टी" तत्व पर "न्यूनतम/अधिकतम" रेंज है। मूल्यांकन के "अंत में आगे बढ़ने" के द्वारा, आप अन्य फ़िल्टरिंग तत्वों को अनुमति देते हैं जो समग्र अभिव्यक्ति के लिए अधिक महत्वपूर्ण हैं ("ई" के कम संभावित मैचों को स्कैन करने से पहले मुख्य कारक होने के लिए निर्धारित करें, हालांकि मूल रूप से "सब कुछ" ।

यह थोड़ा डीबीए है, लेकिन नोएसक्यूएल दुनिया में मुझे विश्वास है कि यह प्रोग्रामर समस्या बन जाता है।

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

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