بهینه‌سازی پُرسمان‌ها با فیلترهای محدوده و نابرابری در چند فیلد

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

قبل‌از بهینه‌سازی پُرسمان‌هایتان، درباره مفاهیم مرتبط بخوانید.

بهینه‌سازی پُرسمان‌ها با Query Explain

برای تعیین اینکه آیا پُرسمان و نمایه‌های شما بهینه هستند یا نه، می‌توانید از توضیح پُرسمان استفاده کنید تا خلاصه طرح پُرسمان و آمار اجرای پُرسمان را دریافت کنید:

جاوا

Query q = db.collection("employees").whereGreaterThan("salary",
100000).whereGreaterThan("experience", 0);

ExplainResults<QuerySnapshot> explainResults = q.explain(ExplainOptions.builder().analyze(true).build()).get();
ExplainMetrics metrics = explainResults.getMetrics();

PlanSummary planSummary = metrics.getPlanSummary();
ExecutionStats executionStats = metrics.getExecutionStats();

System.out.println(planSummary.getIndexesUsed());
System.out.println(stats.getResultsReturned());
System.out.println(stats.getExecutionDuration());
System.out.println(stats.getReadOperations());
System.out.println(stats.getDebugStats());

Node.js

let q = db.collection("employees")
      .where("salary", ">", 100000)
      .where("experience", ">",0);

let options = { analyze : 'true' };
let explainResults = await q.explain(options);

let planSummary = explainResults.metrics.planSummary;
let stats = explainResults.metrics.executionStats;

console.log(planSummary);
console.log(stats);

مثال زیر نشان می‌دهد که چگونه استفاده از ترتیب صحیح نمایه تعداد ورودی‌های نمایه‌ای را که Cloud Firestore اسکن می‌کند کاهش می‌دهد.

پُرسمان‌های ساده

با مثال قبلی از مجموعه کارمندان، پُرسمان ساده‌ای که با نمایه (experience ASC, salary ASC) اجرا می‌شود به‌صورت زیر است:

جاوا

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("experience")
  .orderBy("salary");

پُرسمان ۹۵۰۰۰ ورودی نمایه را اسکن می‌کند تا فقط پنج سند را برگرداند. ازآنجایی‌که گزاره پُرسمان برآورده نمی‌شود، تعداد زیادی از ورودی‌های نمایه خوانده می‌شوند اما فیلتر می‌شوند.

// Output query planning info
{
    "indexesUsed": [
        {
            "properties": "(experience ASC, salary ASC, __name__ ASC)",
            "query_scope": "Collection"
        }
    ],

    // Output Query Execution Stats
    "resultsReturned": "5",
    "executionDuration": "2.5s",
    "readOperations": "100",
    "debugStats": {
        "index_entries_scanned": "95000",
        "documents_scanned": "5",
        "billing_details": {
            "documents_billable": "5",
            "index_entries_billable": "95000",
            "small_ops": "0",
            "min_query_cost": "0"
        }
    }
}

از تخصص دامنه می‌توانید استنباط کنید که اکثر کارمندان حداقل کمی تجربه خواهند داشت اما تعداد کمی از آن‌ها حقوقی بیشتر از ۱۰۰۰۰۰ خواهند داشت. با توجه به این اطلاعات آماری، می‌توانید ببینید که محدودیت salary گزینشی‌تر از محدودیت experience است. برای تأثیرگذاری بر نمایه‌ای که Cloud Firestore برای اجرای پُرسمان استفاده می‌کند، عبارت orderBy را مشخص کنید که محدودیت salary را قبل‌از محدودیت experience مرتب می‌کند.

جاوا

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

وقتی به‌طور صریح از عبارت orderBy() برای افزودن گزاره‌ها استفاده می‌کنید، Cloud Firestore از نمایه (salary ASC, experience ASC) برای اجرای پُرسمان استفاده می‌کند. ازآنجایی‌که گزینش‌پذیری اولین فیلتر محدوده در این پُرسمان بالاتر است درمقایسه با پُرسمان قبلی، پُرسمان سریع‌تر اجرا می‌شود و مقرون‌به‌صرفه‌تر است.

// Output query planning info
{
    "indexesUsed": [
        {
            "properties": "(salary ASC, experience ASC, __name__ ASC)",
            "query_scope": "Collection"
        }
    ],

    // Output Query Execution Stats
    "resultsReturned": "5",
    "executionDuration": "0.2s",
    "readOperations": "6",
    "debugStats": {
        "index_entries_scanned": "1000",
        "documents_scanned": "5",
        "billing_details": {
            "documents_billable": "5",
            "index_entries_billable": "1000",
            "small_ops": "0",
            "min_query_cost": "0"
        }
    }
}

حالا چه می‌شود