اجرای پرس و جو را با Query Explain تجزیه و تحلیل کنید

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

استفاده از توضیح پرس و جو

شما می‌توانید از Query Explain برای درک نحوه اجرای کوئری‌های خود استفاده کنید. این ابزار جزئیاتی را ارائه می‌دهد که می‌توانید برای بهینه‌سازی کوئری‌های خود از آنها استفاده کنید.

شما می‌توانید از طریق کنسول گوگل کلود یا دستور explain از Query Explain استفاده کنید.

کنسول

یک پرس و جو (query) را در ویرایشگر پرس و جو (Query Editor) اجرا کنید و تب توضیحات (Explanation) را باز کنید:

  1. در کنسول گوگل کلود، به صفحه پایگاه‌های داده بروید.

    به پایگاه‌های داده بروید

  2. از لیست پایگاه‌های داده، یک پایگاه داده Cloud Firestore را انتخاب کنید. کنسول Google Cloud، Firestore Explorer را برای آن پایگاه داده باز می‌کند.
  3. یک پرس و جو (query) در ویرایشگر پرس و جو (query editor) وارد کنید و روی اجرا (Run) کلیک کنید.
  4. برای مشاهده خروجی تحلیل پرس و جو، روی تب Explanation کلیک کنید.

    تب توضیح کوئری در کنسول
رابط برنامه‌نویسی کاربردی مونگودی‌بی

توضیح پرس‌وجو در API MongoDB از طریق دستور explain پشتیبانی می‌شود که می‌توانید در ابزارهایی مانند Mongo Shell و Compass از آن استفاده کنید.

دستور explain با دستورات aggregate ، find ، distinct و count پشتیبانی می‌شود، برای مثال:

db.collection.explain('executionStats').find(...)

همچنین می‌توانید از متد explain() استفاده کنید، برای مثال:

db.collection.find({QUERY}).explain('executionStats')
محدودیت‌ها
به محدودیت‌ها و تفاوت‌های زیر توجه کنید:
  • کوئری Explain از دستوراتی که مکان‌نما را برمی‌گردانند پشتیبانی نمی‌کند. برای مثال، فراخوانی explain با فراخوانی مستقیم دستور زیر پشتیبانی نمی‌شود:

    db.collection.aggregate(..., explain: true)
  • توضیح پرس‌وجو فقط در دستورات find ، aggregate ، count ، distinct ، update ، delete و findAndModify پشتیبانی می‌شود.

  • Query Explain از حالت‌های executionStats ، allPlansExecution و queryPlanner verbosity پشتیبانی می‌کند.

    • queryPlanner : فقط طرح اجرا را برمی‌گرداند، بدون اجرای پرس‌وجو،
    • executionStats و allPlansExecution : طرح اجرا را به همراه آمار مربوط به صورتحساب، حافظه و اجرا برمی‌گرداند.

    اگر هیچ حالت verbosity مشخص نشده باشد، پوسته به طور پیش‌فرض روی queryPlanner قرار می‌گیرد. برای مشاهده آمار کامل اجرا، باید حالت verbosity مربوط executionStats یا allPlansExecution را مشخص کنید.

تحلیل

خروجی Query Explain شامل دو جزء اصلی است - آمار خلاصه و درخت اجرا. این پرس و جو را به عنوان مثال در نظر بگیرید:

db.orders.aggregate(
 [
   { "$match": { "user_id": 1234 } },
   { "$sort": { "date_placed": 1 } }
 ]
)

خلاصه آمار

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

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

درخت اجرا

درخت اجرا، اجرای پرس‌وجو را به صورت مجموعه‌ای از گره‌ها توصیف می‌کند. گره‌های پایینی (گره‌های برگ) داده‌ها را از لایه ذخیره‌سازی بازیابی می‌کنند که در امتداد درخت حرکت می‌کند تا پاسخ پرس‌وجو را تولید کند.

برای جزئیات مربوط به هر گره اجرایی، به مرجع اجرا مراجعه کنید.

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

مثال زیر یک درخت اجرا است:

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

Tree:
• Compute
|  $out_1: map_set($record_1, "__id__", $__id___1, "__key__", unset)
|  is query result: true
|
|  Execution:
|   records returned: 35
|   latency: 204.87 ms (local 7.64 ms)
|
└── • Compute
    |  $__id___1: _id($__key___2)
    |
    |  Execution:
    |   records returned: 35
    |   latency: 197.23 ms (local 2.04 ms)
    |
    └── • MajorSort
        |  fields: [$v_5 ASC]
        |  output: [$__key___2, $record_1]
        |
        |  Execution:
        |   records returned: 35
        |   latency: 195.20 ms (local 28.42 ms)
        |   peak memory usage: 45.56 KiB (46,656 B)
        |
        └── • Compute
            |  $v_5: offset($v_4, 0L)
            |
            |  Execution:
            |   records returned: 35
            |   latency: 166.78 ms (local 14.84 ms)
            |
            └── • Compute
                |  $v_4: sortPaths(array($date_placed_1), [date_placed ASC])
                |
                |  Execution:
                |   records returned: 35
                |   latency: 151.94 ms (local 5.43 ms)
                |
                └── • TableScan
                       source: **/orders
                       order: STABLE
                       filter: $eq($user_id_1, 1,234)
                       output bindings: {$__key___2=row().__key__, $date_placed_1=row().date_placed, $record_1=row[* - { __create_time__, __update_time__ }](), $user_id_1=row().user_id}
                       output: [$__key___2, $date_placed_1, $record_1]

                       Execution:
                        records returned: 35
                        latency: 146.50 ms
                        data bytes returned: 3.25 KiB (3,325 B)
                        post-filtered rows: 230
                        records scanned: 265
                        data bytes read: 24.58 KiB (25,175 B)

قدم بعدی چیست؟