مرجع تنفيذ طلب البحث

توضّح هذه الصفحة ناتج طلب بحث تم تنفيذه باستخدام ميزة "تفسير طلب البحث". لمعرفة كيفية تنفيذ طلب بحث باستخدام ميزة "تفسير طلب البحث"، يُرجى الاطّلاع على تحليل تنفيذ طلب البحث باستخدام ميزة "تفسير طلب البحث".

المفاهيم الشائعة

يتم استخدام المفاهيم والمصطلحات الشائعة التالية في جميع أنحاء شجرة التنفيذ.

الصفوف والسجلات

يُستخدم المصطلحان صف وسجلّ للإشارة بشكل عام إلى مستند أو إدخال فهرس.

المتغيرات

يشير الرمز $ إلى متغيّر يتم إنشاؤه أو الإشارة إليه في شجرة التنفيذ. على سبيل المثال: $foo_1. تُستخدم هذه المتغيّرات عادةً للإشارة إلى محتوى مستند أو قيمة تعبير تم تقييمه أثناء تنفيذ طلب بحث.

يمكن أن تظهر المتغيّرات الداخلية التالية في عُقد التنفيذ:

  • ‫$__key__: المفتاح هو معرّف داخلي لمستند. هذا معرّف فريد ومطلق يتضمّن المشروع وقاعدة البيانات والمسار الكامل للمستند.
  • $__id__: المعرّف هو معرّف فريد لمستند ضمن مجموعته. ويكون هذا المعرّف فريدًا ضمن مجموعة واحدة.
  • ‫$rid: رقم تعريف الصف هو معرّف داخلي لمستند في مساحة التخزين. ويكون هذا المعرّف فريدًا ضمن مجموعة واحدة.

لنفترض أنّ عقدة Compute تُستخدَم لاحتساب __id__ من المستند __key__:

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. تشير السمة keys في العقدة Scan إلى اسم المتغيّر لكل مفتاح في تعريف الفهرس، بالترتيب. يمكن استخدام المتغيّرات للإشارة إلى قيم وقت التشغيل للحقل الذي تم فحصه في أعلى شجرة التنفيذ.

في المثال التالي، يتم ربط قيمة حقل 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 كامل، ولكنه أقل كفاءة من SequentialScan واحد على فهرس مركب من ["b" ASC, "a" ASC].

• 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 في وقت التشغيل وقيد "2025-08-10" على date_placed لتقييد نطاقات الفحص.

• 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، فسيظل مضمنًا، مع قيم null للأعمدة من جانب map.

• 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

لتنفيذ عملية ترتيب على مجموعة ثابتة من المواقع الإلكترونية يتم عرض جميع السجلات في الذاكرة مرة واحدة وإرجاع القيم المرتبة بالترتيب، ويكون حجم مجموعة الترتيب محدودًا بحد ذاكرة طلب البحث.

عند توفير حد لاحق، يتم استخدام خوارزمية ترتيب top-k لتقليل استخدام الذاكرة. باستخدام هذه الطريقة، يمكن إجراء عمليات الفرز على مجموعة كبيرة عشوائيًا من السجلات طالما أنّ الذاكرة المستخدمة لتخزين العناصر الـ k التي تم أخذها في الاعتبار لا تتجاوز الحدّ الأقصى.

• 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