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

क्वेरी के धीमे होने की समस्या को हल करने के लिए, क्वेरी के एक्ज़ीक्यूशन प्लान और रनटाइम एक्ज़ीक्यूशन प्रोफ़ाइल पाने के लिए, 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]}}}) या let में तय किए गए फ़ील्ड और वैरिएबल के बीच समानता की तुलना (eq या in) से करती है (उदाहरण के लिए, {$match: {$expr: {$eq: [a, "$$a"]}}}), फ़ॉरेन कलेक्शन में शामिल फ़ील्ड पर इंडेक्स बनाएं. ध्यान दें कि प्लैनिंग में मल्टीकी इंडेक्स का इस्तेमाल नहीं किया जाएगा.

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

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

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

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

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

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

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