क्वेरी की परफ़ॉर्मेंस ऑप्टिमाइज़ करना

क्वेरी के धीमे होने की समस्या को ठीक करने के लिए, क्वेरी के एक्ज़ीक्यूशन प्लान और रनटाइम एक्ज़ीक्यूशन प्रोफ़ाइल पाने के लिए, Query Explain का इस्तेमाल करें. यहां दिए गए सेक्शन में, एक्ज़ीक्यूशन प्रोफ़ाइल के हिसाब से क्वेरी की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, अपनाए जा सकने वाले तरीकों के बारे में बताया गया है:

नतीजों की संख्या सीमित करना

यह पता करने के लिए कि क्वेरी से कई दस्तावेज़ मिल रहे हैं या नहीं, एक्ज़ीक्यूशन ट्री में, रिकॉर्ड वापस लाए गए फ़ील्ड का इस्तेमाल करें. $limit क्लॉज़ का इस्तेमाल करके, क्वेरी से मिलने वाले दस्तावेज़ों की संख्या को सीमित करें. इससे, नेटवर्क पर क्लाइंट को वापस भेजे जाने वाले नतीजों के सीरियल में मौजूद बाइट का साइज़ कम हो जाता है. जिन मामलों में Limit नोड से पहले MajorSort नोड होता है उनमें क्वेरी इंजन, Limit और MajorSort नोड को एक साथ जोड़ सकता है. साथ ही, इन-मेमोरी मैटेरियलाइज़ेशन और सॉर्ट को TopN सॉर्ट से बदल सकता है. इससे क्वेरी के लिए मेमोरी की ज़रूरत कम हो जाती है.

नतीजे के तौर पर मिलने वाले दस्तावेज़ का साइज़ सीमित करना

ज़रूरी न होने वाले फ़ील्ड फ़ेच करने से बचने के लिए, $project क्लॉज़ का इस्तेमाल करके, क्वेरी से मिलने वाले दस्तावेज़ के साइज़ को सीमित करें. इससे, इंटरमीडिएट नतीजों को प्रोसेस करने में लगने वाले कंप्यूट और मेमोरी के खर्च को कम करने में मदद मिलती है. साथ ही, नेटवर्क पर क्लाइंट को वापस भेजे जाने वाले नतीजों के सीरियल में मौजूद बाइट का साइज़ भी कम हो जाता है. जिन मामलों में क्वेरी में रेफ़र किए गए सभी फ़ील्ड, सामान्य इंडेक्स (मल्टीकी नहीं) में शामिल होते हैं उनमें क्वेरी को पूरी तरह से इंडेक्स स्कैन किया जा सकता है. इससे, प्राइमरी स्टोरेज से दस्तावेज़ फ़ेच करने की ज़रूरत नहीं पड़ती.

इंडेक्स का इस्तेमाल करना

इंडेक्स सेट अप और ऑप्टिमाइज़ करने के लिए, यहां दिए गए निर्देशों का पालन करें.

यह पता करना कि क्वेरी किसी इंडेक्स का इस्तेमाल कर रही है या नहीं

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

यह पता करना कि इस्तेमाल किए गए इंडेक्स को ऑप्टिमाइज़ किया जा सकता है या नहीं

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

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

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

$lookup क्वेरी ऑप्टिमाइज़ करना

from कलेक्शन में इंडेक्स जोड़कर, $lookup क्वेरी को ऑप्टिमाइज़ किया जा सकता है. इससे, पूरी कलेक्शन को स्कैन किए बिना, ऑपरेशन के ज़रिए मैच करने वाले दस्तावेज़ों को आसानी से ढूंढा जा सकता है.

localField और foreignField के साथ $lookup

अगर $lookup स्टेज में localField और foreignField विकल्पों का इस्तेमाल किया जा रहा है, तो from कलेक्शन में foreignField पर इंडेक्स बनाएं.

नेस्टेड पाइपलाइन के साथ $lookup

अगर $lookup स्टेज में pipeline विकल्प का इस्तेमाल, $match स्टेज के साथ किया जा रहा है, तो पूरी कलेक्शन को स्कैन करने से बचने के लिए, फ़ॉरेन कलेक्शन में शामिल फ़ील्ड पर इंडेक्स बनाएं:

  • फ़िल्टर सिमैंटिक वाले $match स्टेज के लिए (उदाहरण के लिए {$match: {a: true}}), फ़ॉरेन कलेक्शन (a) में शामिल फ़ील्ड पर इंडेक्स बनाएं.
  • एग्रीगेशन सिमैंटिक वाले $match स्टेज के लिए, जो किसी फ़ील्ड की तुलना किसी कॉन्स्टैंट वैल्यू से करता है (उदाहरण के लिए {$match: {$expr: {$gt: [a, 10]}}}) या फ़ॉरेन कलेक्शन में शामिल फ़ील्ड पर इंडेक्स बनाएं.eqinlet{$match: {$expr: {$eq: [a, "$$a"]}}} ध्यान दें कि प्लानिंग में मल्टीकी इंडेक्स का इस्तेमाल नहीं किया जाएगा.

इंडेक्स बनाना

इंडेक्स बनाने के लिए, इंडेक्स मैनेजमेंट से जुड़ा दस्तावेज़ देखें . यह पक्का करने के लिए कि आपकी क्वेरी, इंडेक्स का इस्तेमाल कर सकती है, सामान्य (मल्टीकी नहीं) इंडेक्स बनाएं. इनमें फ़ील्ड को इस क्रम में रखें:

  1. समानता वाले ऑपरेटर में इस्तेमाल किए जाने वाले सभी फ़ील्ड. क्वेरी में फिर से इस्तेमाल करने की संभावना को ज़्यादा से ज़्यादा करने के लिए, क्वेरी में समानता वाले ऑपरेटर में फ़ील्ड के दिखने के क्रम के हिसाब से, फ़ील्ड को घटते क्रम में रखें.
  2. सॉर्ट किए जाने वाले सभी फ़ील्ड (एक ही क्रम में).
  3. क्वेरी की कंस्ट्रेंट सेलेक्टिविटी के घटते क्रम में, रेंज या असमानता वाले ऑपरेटर में इस्तेमाल किए जाने वाले फ़ील्ड.
  4. इंडेक्स में क्वेरी के हिस्से के तौर पर वापस लाए जाने वाले फ़ील्ड: ऐसे फ़ील्ड को इंडेक्स में शामिल करने से, इंडेक्स क्वेरी को कवर कर पाता है. साथ ही, प्राइमरी स्टोरेज से दस्तावेज़ फ़ेच करने की ज़रूरत नहीं पड़ती.

ऐरे फ़ील्ड को फ़िल्टर और सॉर्ट करने वाली क्वेरी के लिए, मल्टीकी इंडेक्स बनाने पर विचार करें.

क्वेरी हिंट का इस्तेमाल करना

अगर आपने क्वेरी के लिए ज़्यादा काम का इंडेक्स बनाया है, लेकिन क्वेरी इंजन उस इंडेक्स का इस्तेमाल नहीं कर रहा है, तो क्वेरी हिंट का इस्तेमाल करके, क्वेरी इंजन की इंडेक्स प्राथमिकता को बदला जा सकता है.

Query Explain की मदद से एक्ज़ीक्यूट की गई क्वेरी के आउटपुट के बारे में ज़्यादा जानने के लिए, क्वेरी के एक्ज़ीक्यूशन का रेफ़रंस देखें.