پرس و جوها را با فیلترهای محدوده و نابرابری در چندین فیلد بهینه کنید

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

قبل از اینکه کوئری‌های خود را بهینه کنید، در مورد مفاهیم مرتبط مطالعه کنید.

بهینه‌سازی کوئری‌ها با استفاده از Query Explain

برای تعیین اینکه آیا پرس‌وجو و شاخص‌های شما بهینه هستند یا خیر، می‌توانید از 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());

نود جی اس

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"
        }
    }
}

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