इस पेज पर, Query Explain की मदद से एक्ज़ीक्यूट की गई क्वेरी के आउटपुट के बारे में बताया गया है. Query Explain की मदद से क्वेरी एक्ज़ीक्यूट करने का तरीका जानने के लिए, Query Explain की मदद से क्वेरी के एक्ज़ीक्यूशन का विश्लेषण करना लेख पढ़ें.
सामान्य कॉन्सेप्ट
एक्ज़ीक्यूशन ट्री में, इन सामान्य कॉन्सेप्ट और शब्दों का इस्तेमाल किया गया है.
लाइनें और रिकॉर्ड
लाइन और रिकॉर्ड शब्दों का इस्तेमाल, किसी दस्तावेज़ या इंडेक्स एंट्री के लिए किया जाता है.
वैरिएबल
$ का मतलब वैरिएबल है. इसे एक्ज़ीक्यूशन ट्री में बनाया या
रेफ़र किया जाता है. उदाहरण के लिए: $foo_1. आम तौर पर, इन वैरिएबल का इस्तेमाल किसी दस्तावेज़ के कॉन्टेंट या क्वेरी के एक्ज़ीक्यूशन के दौरान, आकलन किए गए एक्सप्रेशन की वैल्यू को रेफ़र करने के लिए किया जाता है.
एक्ज़ीक्यूशन नोड में, ये इंटरनल वैरिएबल दिख सकते हैं:
$__key__- कुंजी, किसी दस्तावेज़ के लिए इंटरनल आइडेंटिफ़ायर होती है. यह प्रोजेक्ट, डेटाबेस, और दस्तावेज़ के पूरे पाथ के साथ, एक ऐब्सलूट और यूनीक आइडेंटिफ़ायर होता है.$__id__- आईडी, किसी कलेक्शन में मौजूद दस्तावेज़ के लिए यूनीक आइडेंटिफ़ायर होता है. यह किसी एक कलेक्शन में यूनीक होता है.$rid- लाइन आईडी, स्टोरेज में मौजूद किसी दस्तावेज़ के लिए इंटरनल आइडेंटिफ़ायर होता है. यह किसी एक कलेक्शन में यूनीक होता है.
यहां एक उदाहरण दिया गया है, जिसमें Compute नोड का इस्तेमाल करके, दस्तावेज़ __key__ से __id__ का आकलन किया गया है:
Compute
| $__id__1: _id($__key__)
| records returned: 1
बाधाएं और रेंज
कुछ स्कैन नोड, स्कैन की गई वैल्यू की रेंज के बारे में बताने के लिए, constraints और ranges एट्रिब्यूट का इस्तेमाल करते हैं. इन एट्रिब्यूट में, रेंज ट्री फ़ॉर्मैट का इस्तेमाल किया जाता है. इसमें वैल्यू की सूची शामिल होती है. ये वैल्यू, कुंजियों की क्रम से लगाई गई सूची से जुड़ी होती हैं. यह सूची, इंडेक्स की परिभाषा में दिखती है. उदाहरण के लिए, ट्री में दिखने वाली पहली रेंज, यहां (1..5], कुंजियों की क्रम से लगाई गई सूची में मौजूद पहली कुंजी,
यहां a, पर लागू होने वाली बाधाओं से जुड़ी होती है:
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
इंडेंटेशन का हर लेवल, सूची में मौजूद अगली कुंजी पर लागू होने वाली बाधा को दिखाता है. स्क्वेयर ब्रैकेट, शामिल की गई रेंज को दिखाते हैं. वहीं, राउंड ब्रैकेट, शामिल न की गई रेंज को दिखाते हैं. इस मामले में, बाधा का मतलब है 1 < "a" <= 5, और
"b" = 1.
a के लिए एक से ज़्यादा ब्रांच वाले इस उदाहरण में,
बाधा का मतलब है 1 < a <= 5 OR a = 10:
| constraints: /
|----(1L, 5L]
|----[10L]
कुंजी वैरिएबल
SequentialScan जैसे कुछ स्कैन नोड में, index एट्रिब्यूट के हिस्से के तौर पर कुंजियों की सूची और keys एट्रिब्यूट, दोनों Scan नोड में मौजूद होते हैं. Scan नोड में मौजूद keys एट्रिब्यूट, क्रम से इंडेक्स की परिभाषा में मौजूद हर कुंजी के वैरिएबल के नाम को दिखाता है. एक्ज़ीक्यूशन ट्री में आगे, स्कैन किए गए फ़ील्ड की रनटाइम वैल्यू को रेफ़र करने के लिए, वैरिएबल का इस्तेमाल किया जा सकता है.
यहां दिए गए उदाहरण में, मौजूदा दस्तावेज़ के लिए user फ़ील्ड की वैल्यू
, वैरिएबल $user_1 पर मैप होती है. वहीं, date_placed की वैल्यू, $date_placed_1 पर मैप होती है.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
एक्ज़ीक्यूशन नोड
क्वेरी के एक्ज़ीक्यूशन ट्री में, ये नोड शामिल हो सकते हैं.
SeekingScan
यह एक डाइनैमिक स्कैन को दिखाता है. इसमें, दिखाई गई लाइनें, इंडेक्स की क्रम से लगाई गई एक रेंज में नहीं हो सकती हैं. साथ ही, क्वेरी को पूरा करने के लिए, अलग-अलग कई स्कैन किए जा सकते हैं.
उदाहरण के लिए, ऐसी क्वेरी जिसमें a मौजूद है और b की वैल्यू 1 है,
["a" ASC, "b" ASC] के इंडेक्स पर काम करने वाली ऐसी क्वेरी, a की हर अलग वैल्यू के लिए, अलग-अलग और क्रम से न लगाई गई रेंज को स्कैन करके दिखाएगी.
यह TableScan से ज़्यादा बेहतर है. हालांकि, ["b" ASC, "a" ASC] के कंपोज़िट इंडेक्स पर किए गए
SequentialScan से कम बेहतर है.
• SeekingScan
| constraints: /
|----(-∞..+∞)
|----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1
SequentialScan
यह स्टोरेज में मौजूद लाइनों की क्रम से लगाई गई स्टैटिक रेंज के स्कैन को दिखाता है. इसे एक बार में पढ़ा जा सकता है.
key ordering length का मतलब है कि कुंजियों की वह संख्या जिसे मूल कुंजी के क्रम में सेव और दिखाया जाना चाहिए. [k1, k2, k3] के स्कीमा के लिए, कुंजी के क्रम की लंबाई 0 होने का मतलब है कि स्कैन के नतीजे किसी भी क्रम में दिखाए जा सकते हैं. 1 का मतलब है कि नतीजे k1 के क्रम में दिखाए जाएंगे. हालांकि, k1 की एक जैसी वैल्यू वाली लाइनें किसी भी क्रम में दिखाई जा सकती हैं. 3 का मतलब है कि दस्तावेज़, क्रम से सॉर्ट किए गए क्रम में दिखाए जाएंगे.
• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1
UniqueScan
यह स्टोरेज में मौजूद लाइनों की क्रम से लगाई गई स्टैटिक रेंज के स्कैन को दिखाता है. इसमें, लाइनों को डुप्लीकेट होने से बचाने के लिए, इन-मेमोरी डिडुप्लीकेशन का इस्तेमाल किया जाता है.
• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
|----(-∞..+∞)
| records returned: 1
| records scanned: 1
IndexSeek
यह एक डाइनैमिक स्कैन को दिखाता है. इसमें, दिखाई गई लाइनें, रनटाइम डेटा के हिसाब से पैरामीटर वाली हो सकती हैं. साथ ही, ये इंडेक्स की क्रम से लगाई गई एक रेंज में नहीं हो सकती हैं. क्वेरी को पूरा करने के लिए, अलग-अलग कई स्कैन किए जा सकते हैं.
उदाहरण के लिए, ["user" ASC, "date_placed" ASC] के इंडेक्स पर काम करने वाली ऐसी क्वेरी जिसमें user की वैल्यू $user_id के बराबर है और date_placed की वैल्यू
"2025-08-10" के बराबर है, स्कैन की रेंज को सीमित करने के लिए, रनटाइम में $user_id वैरिएबल की वैल्यू और date_placed पर "2025-08-10"
की बाधा का इस्तेमाल करेगी.
• IndexSeek
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| fields: [$user_1 ASC, $date_placed_1 ASC, $rid ASC]
| key: $key_1
| filter: equal($user_1, $user_id) AND equal($date_placed_1, "2025-08-10")
| records returned: 1
| records scanned: 1
लाएं
यह दी गई लाइन के आइडेंटिफ़ायर को प्राइमरी स्टोरेज से लाइन के असली कॉन्टेंट से वापस जोड़ता है. अगर किसी पैरंट नोड (या क्वेरी के आखिरी नतीजे) को दस्तावेज़ों के फ़ील्ड के सबसेट की ज़रूरत होती है, तो Fetch का इस्तेमाल करना ज़रूरी है.
• Fetch
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
LookupById
यह किसी दूसरे कलेक्शन में मौजूद दस्तावेज़ों को उनके आईडी के हिसाब से देखकर, जॉइन की प्रोसेस पूरी करता है. जिन आईडी को देखना है वे इनपुट दस्तावेज़ों में मौजूद किसी फ़ील्ड से लिए जाते हैं. लुकअप के नतीजों को, इनपुट दस्तावेज़ों में एक नए फ़ील्ड के तौर पर जोड़ा जाता है.
• LookupById
| local_field: $localField_1
| foreign_datasource: (default)#/**/foreign
| output: $output_1
TableScan
यह किसी कलेक्शन का पूरा और बिना क्रम वाला स्कैन होता है. इसका इस्तेमाल तब किया जाता है, जब कोई क्वेरी, उससे जुड़े इंडेक्स के बिना रन की जाती है.
ऑर्डर STABLE या UNDEFINED हो सकता है. STABLE का मतलब है कि ऑर्डर तय किया गया है.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
NestedLoopJoin
यह डेटा के दो सेट (बाएं और दाएं) के बीच जॉइन की प्रोसेस पूरी करता है. इसके लिए, बाएं इनपुट की हर लाइन को दोहराया जाता है. साथ ही, हर बाईं लाइन के लिए, join_condition के आधार पर मैच होने वाली लाइनों के लिए, दाएं इनपुट को स्कैन किया जाता है.
join_type से पता चलता है कि जॉइन किस तरह का है. उदाहरण के लिए, LEFT_OUTER का मतलब है कि बाएं इनपुट की सभी लाइनें, आउटपुट में कम से कम एक बार शामिल की जाती हैं.
अगर join_condition के आधार पर, बाईं लाइन, दाएं इनपुट में मौजूद किसी लाइन से मैच नहीं होती है, तब भी उसे शामिल किया जाएगा. हालांकि, दाएं इनपुट के कॉलम के लिए, वैल्यू नल होंगी.
• NestedLoopJoin
| join_type: LEFT_OUTER
| join_condition: equal($left, $right)
|
└── • left tree
| ...
└── • right tree
...
HashAggregate
यह एग्रीगेट कार्रवाइयों का हैश-बैक वाला लागू करने का तरीका है. इसके लिए, नतीजे दिखाने से पहले, पूरे ग्रुप को इन-मेमोरी में सेव करना ज़रूरी है. साथ ही, यह क्वेरी की मेमोरी की सीमा से ज़्यादा नहीं होना चाहिए.
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
यह एक खास एग्रीगेट नोड है. यह एक बार में सिर्फ़ एक ग्रुप के लिए स्टेट बनाए रखता है. इससे, पीक मेमोरी का इस्तेमाल कम होता है. इसका इस्तेमाल तब किया जाता है, जब इसके नीचे मौजूद चाइल्ड नोड, ग्रुप को क्रम से दिखाएगा. उदाहरण के लिए, किसी फ़ील्ड की अलग-अलग वैल्यू के हिसाब से ग्रुपिंग करते समय, उस फ़ील्ड पर इंडेक्स का इस्तेमाल करना.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
यह प्रॉपर्टी के तय सेट पर सॉर्ट करने की प्रोसेस पूरी करता है. यह सभी रिकॉर्ड को एक साथ मेमोरी में सेव करता है और सॉर्ट की गई वैल्यू को क्रम से दिखाता है. सॉर्ट सेट का साइज़, क्वेरी की मेमोरी की सीमा से सीमित होता है.
जब बाद में कोई सीमा तय की जाती है, तो मेमोरी के इस्तेमाल को कम करने के लिए, टॉप-के सॉर्टिंग एल्गोरिदम का इस्तेमाल किया जाता है. इसकी मदद से, रिकॉर्ड के किसी भी बड़े सेट को सॉर्ट किया जा सकता है. इसके लिए ज़रूरी है कि के कंसीडर किए गए एलिमेंट को सेव करने के लिए इस्तेमाल की गई मेमोरी, तय सीमा से ज़्यादा न हो.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
यह कई चाइल्ड नोड के नतीजों को जोड़ता है और पैरंट नोड को नतीजे दिखाता है. यह नोड, एक से ज़्यादा चाइल्ड नोड में दिखने वाले नतीजों को डुप्लीकेट होने से नहीं बचाता है. साथ ही, दिखाए गए नतीजों का क्रम तय नहीं होता है.
• Concat
├── • Fetch
...
├── • Fetch
कंप्यूट
यह एक्सप्रेशन के सेट का आकलन करता है और नतीजों को वैरिएबल के सेट में असाइन करता है.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
फ़िल्टर
यह चुनिंदा तौर पर लाइनें दिखाता है. हालांकि, ऐसा तब ही होता है, जब वे दिए गए एक्सप्रेशन से मैच होती हैं.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
RecordCount
यह चाइल्ड नोड से जनरेट होने वाली लाइनों की संख्या को गिनता है और count एट्रिब्यूट में तय किए गए वैरिएबल को मौजूदा संख्या दिखाता है.
• RecordCount
| count: $row_number_1
| records returned: 1
वैल्यू
यह काम करने के लिए, लिटरल वैल्यू की एक सीरीज़ जनरेट करता है. इसका इस्तेमाल मुख्य तौर पर तब किया जाता है, जब क्वेरी के इनपुट के तौर पर, दस्तावेज़ों की सेट लिस्ट दी जाती है.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Unnest
यह चाइल्ड नोड से जनरेट होने वाली वैल्यू को अननेस्ट करता है.
• Unnest
| expression: foo AS unnested_foo
सीमा
यह पैरंट नोड को दिखाई जाने वाली लाइनों की संख्या को सीमित करता है.
• Limit
| limit: 10
| records returned: 1
ऑफ़सेट
यह चाइल्ड नोड से जनरेट होने वाली लाइनों की तय संख्या को छोड़ देता है.
• Offset
| offset: 10
| records returned: 1