توضّح هذه الصفحة ناتج استعلام تم تنفيذه باستخدام Query Explain. للتعرّف على كيفية تنفيذ طلب بحث باستخدام Query Explain، راجِع مقالة تحليل تنفيذ طلب البحث باستخدام Query Explain.
المفاهيم الشائعة
يتم استخدام المفاهيم والمصطلحات الشائعة التالية في شجرة التنفيذ.
الصفوف والسجلات
يتم استخدام المصطلحَين صف وسجلّ للإشارة بشكل عام إلى مستند أو إدخال فهرس.
المتغيرات
يشير $
إلى متغيّر يتم إنشاؤه أو الرجوع إليه في شجرة التنفيذ. على سبيل المثال: $foo_1
. تُستخدَم هذه المتغيّرات عادةً للإشارة إلى محتوى مستند أو قيمة تعبير تم تقييمه أثناء تنفيذ طلب بحث.
يمكن أن تظهر المتغيّرات الداخلية التالية في عُقد التنفيذ:
$__key__
-المفتاح هو معرّف داخلي لمستند. وهو معرّف فريد ومطلق يتضمّن المشروع وقاعدة البيانات والمسار الكامل للمستند.$__id__
-المعرّف هو معرّف فريد لمستند ضمن مجموعته. هذا المعرّف فريد ضمن مجموعة واحدة.
لنفترض أنّ هناك مثالاً يتم فيه استخدام عقدة 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
TableAccess
تتم إعادة ربط معرّف الصف المقدَّم بمحتوى الصف الفعلي من وحدة التخزين الأساسية. يجب استخدام TableAccess
إذا كانت العقدة الرئيسية (أو نتيجة طلب البحث النهائي) تتطلّب مجموعة فرعية من الحقول من المستندات.
• TableAccess
| 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
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
تُجري عملية ترتيب على مجموعة ثابتة من السمات. يتم إنشاء جميع السجلات في الذاكرة مرة واحدة وعرض القيم التي تم ترتيبها حسب الترتيب، ويتم تحديد حجم مجموعة الترتيب من خلال الحد الأقصى لذاكرة طلب البحث.
عند توفير حدّ لاحق، يتم استخدام خوارزمية ترتيب أعلى k لتقليل استخدام الذاكرة. باستخدامها، يمكن إجراء عمليات ترتيب على مجموعة كبيرة بشكل عشوائي من السجلات طالما أنّ الذاكرة المستخدمة في تخزين العناصر k التي تم أخذها في الاعتبار لا تتجاوز الحدّ الأقصى.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
تدمج هذه الدالة نتائج عُقد فرعية متعددة وتعرض النتيجة للعقدة الرئيسية. لا تزيل هذه العقدة النتائج المكرّرة التي تظهر في عدة عناصر فرعية، كما أنّ ترتيب النتائج المعروضة غير ثابت.
• Concat
├── • TableAccess
...
├── • TableAccess
الحوسبة
تقيّم هذه الدالة مجموعة من التعبيرات، وتعيّن النتائج لمجموعة من المتغيرات.
• 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
القيم
تنتج هذه الدالة سلسلة من القيم الحرفية التي يمكن العمل عليها. يتم استخدامها بشكل أساسي عندما يتم تقديم مجموعة من المستندات كمدخل لطلب بحث.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Unnest
تؤدي إلى إلغاء تضمين القيمة التي تنتجها العقدة الفرعية.
• Unnest
| expression: foo AS unnested_foo
الحدّ
يحدّ من عدد الصفوف المعروضة للعقدة الرئيسية.
• Limit
| limit: 10
| records returned: 1
Offset
تتخطّى عددًا محدّدًا من الصفوف التي تنتجها العقدة الفرعية.
• Offset
| offset: 10
| records returned: 1