क्वेरी एक्ज़ीक्यूट करने का रेफ़रंस

इस पेज पर, 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 की वैल्यू $user_id के बराबर है और date_placed की वैल्यू "2025-08-10" के बराबर है, जो ["user" ASC, "date_placed" ASC] के इंडेक्स पर काम कर रही है, वह रनटाइम में $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