مرجع اجرای پرس و جو

این صفحه خروجی یک پرس‌وجوی اجرا شده با Query Explain را توضیح می‌دهد. برای یادگیری نحوه اجرای یک پرس‌وجو با Query Explain، به Analyze query execution with Query Explain مراجعه کنید.

مفاهیم رایج

مفاهیم و اصطلاحات رایج زیر در سراسر درخت اجرا استفاده می‌شوند.

ردیف‌ها و رکوردها

اصطلاحات سطر و رکورد به طور کلی برای اشاره به یک سند یا ورودی فهرست استفاده می‌شوند.

متغیرها

$ نشان دهنده متغیری است که در درخت اجرا ایجاد یا به آن ارجاع داده می‌شود. برای مثال: $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]

گره‌های اجرایی

یک درخت اجرای پرس و جو می‌تواند شامل گره‌های زیر باشد.

جستجوی اسکن

نشان دهنده یک اسکن پویا است که در آن ردیف‌های برگردانده شده ممکن است در امتداد یک محدوده متوالی از شاخص نباشند و برای برآورده کردن پرس و جو باید چندین اسکن مجزا انجام شود.

برای مثال، یک پرس‌وجو که در آن a وجود دارد و b برابر با ۱ است و روی شاخصی از ["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

اسکن متوالی

نشان دهنده اسکن یک محدوده ایستا و متوالی از ردیف‌های موجود در حافظه است که می‌تواند در یک عملیات خواندن واحد انجام شود.

key ordering length به تعداد کلیدهایی اشاره دارد که باید حفظ شوند و به ترتیب کلید اصلی بازگردانده شوند. برای یک طرحواره [k1, k2, k3] ، طول ترتیب کلید 0 به این معنی است که اسکن می‌تواند به هر ترتیبی بازگردد، 1 به این معنی است که ردیف‌هایی با مقدار 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
| 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

ایندکس سیک

یک اسکن پویا را نشان می‌دهد که در آن ردیف‌های برگردانده شده ممکن است توسط داده‌های زمان اجرا پارامتری شوند و ممکن است در امتداد یک محدوده متوالی از شاخص نباشند، و ممکن است چندین اسکن مجزا برای برآورده کردن پرس و جو انجام شود.

برای مثال، یک پرس‌وجو که در آن 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

دسترسی به جدول

شناسه ردیف ارائه شده را به محتوای ردیف واقعی از حافظه اصلی متصل می‌کند. اگر یک گره والد (یا نتیجه پرس و جوی نهایی) به زیرمجموعه‌ای از فیلدها از اسناد نیاز داشته باشد، TableAccess مورد نیاز است.

• TableAccess
|  order: PRESERVE_INPUT_ORDER
|  peak memory usage: 4.00 KiB (4,096 B)
|  properties: *
|  records returned: 1

جستجو با شناسه

با جستجوی اسناد در یک مجموعه خارجی بر اساس شناسه آنها، عمل پیوند (join) را انجام می‌دهد. شناسه‌های مورد جستجو از فیلدی در اسناد ورودی گرفته می‌شوند. نتایج جستجو به عنوان یک فیلد جدید به اسناد ورودی اضافه می‌شوند.

• LookupById
|  local_field: $localField_1
|  foreign_datasource: (default)#/**/foreign
|  output: $output_1

اسکن جدول

اسکن کامل و نامرتب یک مجموعه. زمانی استفاده می‌شود که یک پرس‌وجو بدون اندیس مرتبط اجرا شود.

ترتیب می‌تواند STABLE یا UNDEFINED باشد که STABLE نشان‌دهنده‌ی ترتیب قطعی است.

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

حلقه تودرتو (NestedLoopJoin)

با پیمایش هر ردیف از ورودی چپ، و برای هر ردیف چپ، اسکن ورودی راست برای یافتن ردیف‌های منطبق بر اساس join_condition ، عمل پیوند (join) را بین دو مجموعه داده (چپ و راست) انجام می‌دهد.

join_type نوع اتصال را نشان می‌دهد. برای مثال، LEFT_OUTER به این معنی است که تمام ردیف‌های ورودی سمت چپ حداقل یک بار در خروجی گنجانده شده‌اند. اگر یک ردیف سمت چپ بر اساس join_condition با هیچ ردیفی در ورودی سمت راست مطابقت نداشته باشد، همچنان گنجانده خواهد شد، با مقادیر null برای ستون‌های ورودی سمت راست.

• NestedLoopJoin
|  join_type: LEFT_OUTER
|  join_condition: $eq($left, $right)
|
└── • left tree
|     ...
└── • right tree
      ...

هش‌جمع

پیاده‌سازی عملیات تجمیعی با پشتیبانی هش. قبل از بازگرداندن نتیجه، نیاز به پیاده‌سازی کامل گروه در حافظه دارد و نباید از محدودیت حافظه پرس‌وجو تجاوز کند.

• 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]

مرتب‌سازی اصلی

عملیات مرتب‌سازی را روی مجموعه‌ای ثابت از ویژگی‌ها انجام می‌دهد. تمام رکوردهای حافظه را به طور همزمان پیاده‌سازی می‌کند و مقادیر مرتب‌شده را به ترتیب برمی‌گرداند، اندازه مجموعه مرتب‌سازی توسط محدودیت حافظه پرس‌وجو محدود می‌شود.

وقتی محدودیت بعدی ارائه شود، از الگوریتم مرتب‌سازی k تایی برای کاهش استفاده از حافظه استفاده می‌شود. با استفاده از آن، می‌توان مرتب‌سازی‌ها را روی مجموعه‌ای دلخواه و بزرگ از رکوردها انجام داد، البته تا زمانی که حافظه مورد استفاده برای ذخیره k عنصر مورد نظر از حد مجاز تجاوز نکند.

• MajorSort
|  fields: [a ASC, b DESC]
|  limit: 10
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 1

کانکات

نتایج چندین گره فرزند را به هم پیوند می‌دهد و نتیجه را به گره والد برمی‌گرداند. این گره نتایج تکراری که در چندین فرزند ظاهر می‌شوند را حذف نمی‌کند و ترتیب نتایج برگشتی غیرقطعی است.

• 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

تعداد رکوردها

تعداد سطرهای تولید شده توسط گره فرزند را می‌شمارد و تعداد فعلی را به متغیر مشخص شده در ویژگی count ارسال می‌کند.

• RecordCount
|  count: $row_number_1
|  records returned: 1

ارزش‌ها

دنباله‌ای از مقادیر تحت‌اللفظی را برای کار تولید می‌کند. عمدتاً زمانی استفاده می‌شود که فهرستی از اسناد به عنوان ورودی یک پرس‌وجو ارائه می‌شود.

• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]

آنست

مقدار تولید شده توسط گره فرزند را از حالت تودرتو خارج می‌کند.

• Unnest
|  expression: foo AS unnested_foo

حد

تعداد ردیف‌های برگشتی به گره والد را محدود می‌کند.

• Limit
|  limit: 10
|  records returned: 1

افست

از تعداد مشخصی از سطرهای تولید شده توسط گره فرزند صرف نظر می‌کند.

• Offset
|  offset: 10
|  records returned: 1