בדף הזה מופיעות דוגמאות לאסטרטגיות של הוספה לאינדקס שאפשר להשתמש בהן בשאילתות עם מסנני טווח ואי-שוויון בכמה שדות, כדי ליצור חוויית שאילתה יעילה.
לפני שמבצעים אופטימיזציה של השאילתות, מומלץ לקרוא על המושגים שקשורים למסנני טווח ומסנני אי-שוויון בכמה נכסים .
אופטימיזציה של שאילתות באמצעות Query Explain
כדי לבדוק אם השאילתה והאינדקסים שבהם נעשה שימוש הם אופטימליים, אפשר ליצור שאילתה באמצעות Query Explain ולעיין בסיכום הביצוע.
Java
...
// Build the query
Query query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("experience"), OrderBy("salary"))
.build();
// Set the explain options to get back *only* the plan summary
QueryResults results = datastore.run(query, ExplainOptions.newBuilder().build());
// Get the explain metrics
Optional explainMetrics = results.getExplainMetrics();
if (!explainMetrics.isPresent()) {
throw new Exception("No explain metrics returned");
}
// Get the plan summary
PlanSummary planSummary = explainMetrics.get().getPlanSummary();
Listבדוגמה הבאה אפשר לראות איך שימוש בסדר הנכון של האינדקס חוסך את מספר הישויות ש-Firestore במצב Datastore סורק.
שאילתות פשוטות
בדוגמה הקודמת של אוסף עובדים, השאילתה הפשוטה שמופעלת עם האינדקס (salary, experience) היא:
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY experience, salary;
Java
Query query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("experience"), OrderBy("salary"))
.build();
השאילתה סורקת 95,000 רשומות באינדקס רק כדי להחזיר 5 ישויות. מספר גדול של רשומות באינדקס נקראו אבל סוננו כי הן לא עמדו בתנאי השאילתה.
// Output query planning info { "indexesUsed": [ { "query_scope": "Collection Group", "properties": "(experience ASC, salary ASC, __name__ ASC)" } ] }, // 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.
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience;
Java
Query query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("salary"), OrderBy("experience"))
.build();
כשמשתמשים באופן מפורש בסעיף orderBy() כדי להוסיף את התנאים בסדר הקודם, Firestore במצב Datastore משתמש באינדקס (salary, experience) כדי להריץ את השאילתה. מכיוון שהסינון לפי הטווח הראשון טוב יותר מהשאילתה הקודמת, השאילתה פועלת מהר יותר ומשתלמת יותר.
// Output query planning info { "indexesUsed": [ { "query_scope": "Collection Group", "properties": "(salary ASC, experience ASC, __name__ ASC)" } ], // 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" } } }