בדף הזה מפורטות דוגמאות לאסטרטגיות של הוספה לאינדקס, שבהן אפשר להשתמש בשאילתות עם מסנני טווח ואי-שוויון בשדות מרובים כדי ליצור חוויית שאילתות יעילה.
לפני שאתם מבצעים אופטימיזציה של השאילתות, כדאי לקרוא על המושגים הקשורים.
אופטימיזציה של שאילתות באמצעות Query Explain
כדי לבדוק אם השאילתה והאינדקסים אופטימליים, אתם יכולים להשתמש ב-Query Explain כדי לקבל את סיכום התוכנית לביצוע השאילתה ואת נתוני הביצוע שלה:
Java
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) היא:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
השאילתה סורקת 95,000 רשומות אינדקס רק כדי להחזיר חמישה מסמכים. מכיוון שהפרדיקט של השאילתה לא מתקיים, מספר גדול של רשומות אינדקס נקראות אבל מסוננות.
// 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" } } }
אתם יכולים להסיק מהמומחיות בתחום שלרוב העובדים יהיה לפחות ניסיון מסוים, אבל למעטים תהיה משכורת של יותר מ-100,000. לפי התובנה הזו, אפשר לראות שהאילוץ salary הוא יותר סלקטיבי מהאילוץ experience. כדי להשפיע על האינדקס שבו Cloud Firestore משתמש כדי להריץ את השאילתה, מציינים משפט orderBy שמסדר את האילוץ salary לפני האילוץ experience.
Java
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" } } }