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

इस पेज पर, 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: $eq($user_1, $user_id) AND $eq($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

TableScan

यह किसी कलेक्शन का पूरा और बिना क्रम वाला स्कैन होता है. इसका इस्तेमाल तब किया जाता है, जब कोई क्वेरी, उससे जुड़े इंडेक्स के बिना रन की जाती है.

ऑर्डर STABLE या UNDEFINED हो सकता है. STABLE का मतलब है कि ऑर्डर तय किया गया है.

• TableScan
|  order: STABLE
|  properties: *
|  records returned: 1
|  records scanned: 1
|  source: (default)#/**/collection

लागू करें

यह डेटा के दो सेट (input और map) के बीच जॉइन करता है. इसके लिए, input की हर लाइन को दोहराया जाता है. साथ ही, हर लाइन के लिए, map की ओर से नतीजे स्कैन करके दिखाए जाते हैं.

join_type से पता चलता है कि जॉइन किस तरह का है. उदाहरण के लिए, LEFT_OUTER का मतलब है कि input की सभी लाइनें, आउटपुट में कम से कम एक बार शामिल की जाती हैं. अगर input की किसी लाइन के लिए, map की ओर से कोई नतीजा नहीं मिलता है, तब भी उसे शामिल किया जाएगा. हालांकि, map की ओर से मिलने वाले कॉलम के लिए, null वैल्यू शामिल की जाएंगी.

• Apply
|  join_type: LEFT_OUTER
|
└── • input tree
|     ...
└── • map 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

यह एक्सप्रेशन के सेट का आकलन करता है और नतीजों को वैरिएबल के सेट में असाइन करता है.

• 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