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

Query Explain به شما امکان می‌دهد تا کوئری‌های Cloud Firestore را به backend ارسال کنید و در عوض آمار عملکرد دقیقی از اجرای کوئری backend دریافت کنید. این عملکرد مانند عملیات EXPLAIN [ANALYZE] در بسیاری از سیستم‌های پایگاه داده رابطه‌ای عمل می‌کند.

درخواست‌های توضیح پرس‌وجو را می‌توان با استفاده از کتابخانه‌های کلاینت سرور Firestore ارسال کرد.

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

توضیح پرس و جو:

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

درک پرس و جو، توضیح گزینه‌ها: پیش‌فرض و تحلیل

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

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

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

هزینه Query Explain چقدر است؟

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

وقتی از توضیح پرس‌وجو (Query Explain) به همراه گزینه تحلیل (analyze) استفاده می‌کنید، عملیات فهرست‌بندی و خواندن انجام می‌شوند، بنابراین هزینه پرس‌وجو طبق معمول از شما دریافت می‌شود. هیچ هزینه اضافی برای فعالیت تحلیل وجود ندارد، فقط هزینه معمول برای اجرای پرس‌وجو محاسبه می‌شود.

از گزینه پیش‌فرض برای توضیح پرس‌وجو استفاده کنید

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

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

جاوا (مدیر)

Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();

    
گره (مدیر)

const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;

    

قالب دقیق پاسخ به محیط اجرا بستگی دارد. نتایج برگشتی را می‌توان به JSON تبدیل کرد. برای مثال:

{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

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

از گزینه Query Explain به همراه گزینه analyze استفاده کنید.

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

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

جاوا (مدیر)

Query q = db.collection("col").whereGreaterThan("a", 1);

ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();

ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();

    
گره (مدیر)

const q = db.collection('col').where('country', '=', 'USA');

const options = { analyze : 'true' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;

    

مثال زیر علاوه بر planInfo شیء stats را نیز نشان می‌دهد. فرمت دقیق پاسخ به محیط اجرا بستگی دارد. پاسخ مثال در قالب JSON است.

{
    "resultsReturned": "5",
    "executionDuration": "0.100718s",
    "readOperations": "5",
    "debugStats": {
               "index_entries_scanned": "95000",
               "documents_scanned": "5"
               "billing_details": {
                     "documents_billable": "5",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }

}

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

تفسیر نتایج و انجام تنظیمات

بیایید به یک سناریوی مثالی نگاهی بیندازیم که در آن فیلم‌ها را بر اساس ژانر و کشور تولید جستجو می‌کنیم.

برای روشن شدن موضوع، معادل این کوئری SQL را در نظر بگیرید.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

اگر از گزینه تحلیل استفاده کنیم، معیارهای بازگشتی نشان می‌دهند که پرس‌وجو روی دو فهرست تک‌فیلدی (category ASC, __name__ ASC) و (country ASC, __name__ ASC) اجرا می‌شود. این ابزار ۱۶۵۰۰ ورودی فهرست را اسکن می‌کند، اما فقط ۱۲۰۰ سند را برمی‌گرداند.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

// Output query status
{
    "resultsReturned": "1200",
    "executionDuration": "0.118882s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "16500",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}

برای بهینه‌سازی عملکرد اجرای پرس‌وجو، می‌توانید یک فهرست ترکیبی کاملاً پوشش داده شده (category ASC, country ASC, __name__ ASC) ایجاد کنید.

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

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, country ASC,  __name__ ASC)"}
    ]
}

// Output query stats
{
    "resultsReturned": "1200",
    "executionDuration": "0.026139s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "1200",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}