התכונה Query Explain מאפשרת לשלוח Cloud Firestore שאילתות לקצה העורפי ולקבל בתמורה נתונים סטטיסטיים מפורטים על הביצוע של השאילתות בקצה העורפי. היא פועלת כמו הפעולה EXPLAIN [ANALYZE] במערכות רבות של מסדי נתונים רלציוניים.
אפשר לשלוח בקשות Query Explain באמצעות ספריות הלקוח של שרת Firestore.
תוצאות ההסבר של השאילתה עוזרות להבין איך השאילתות מבוצעות, ומציגות חוסר יעילות ומיקום של צווארי בקבוק סבירים בצד השרת.
הסבר לשאילתה:
- מספק תובנות לגבי שלב תכנון השאילתות, כדי שתוכלו לשנות את האינדקסים של השאילתות ולשפר את היעילות.
- האפשרות 'ניתוח' עוזרת להבין את העלות והביצועים של כל שאילתה, ומאפשרת לכם לחזור במהירות על דפוסי שאילתות שונים כדי לבצע אופטימיזציה של השימוש בהם.
הסבר על האפשרויות של Query Explain: ברירת מחדל וניתוח
אפשר לבצע פעולות של הסבר על שאילתות באמצעות האפשרות ברירת מחדל או האפשרות ניתוח.
באפשרות ברירת המחדל, Query Explain מתכנן את השאילתה, אבל מדלג על שלב ההפעלה. יוחזרו פרטים על השלב בתהליך התכנון. אפשר להשתמש בכלי הזה כדי לבדוק אם לשאילתה יש את האינדקסים הנדרשים, ולהבין באילו אינדקסים נעשה שימוש. לדוגמה, כך תוכלו לוודא ששאילתה מסוימת משתמשת באינדקס מורכב במקום לבצע חיתוך של הרבה אינדקסים שונים.
באמצעות האפשרות analyze, Query Explain מתכנן ומבצע את השאילתה. הפעולה הזו מחזירה את כל המידע שצוין קודם בכלי לתכנון שאילתות, יחד עם נתונים סטטיסטיים מתוך זמן הריצה של ביצוע השאילתה. הנתונים האלה יכללו את פרטי החיוב של השאילתה, יחד עם תובנות ברמת המערכת לגבי ביצוע השאילתה. אתם יכולים להשתמש בכלי הזה כדי לבדוק תצורות שונות של שאילתות ואינדקסים, ולבצע אופטימיזציה של העלות והחביון שלהם.
מה העלות של Query Explain?
כשמשתמשים באפשרות ברירת המחדל של Query Explain, לא מתבצעות פעולות אינדקס או קריאה. לא משנה מה מורכבות השאילתה, תחויבו על פעולת קריאה אחת.
כשמשתמשים באפשרות analyze של Query Explain, מתבצעות פעולות של אינדקס וקריאה, ולכן החיוב על השאילתה מתבצע כרגיל. אין חיוב נוסף על פעילות הניתוח, רק החיוב הרגיל על השאילתה שמופעלת.
שימוש באפשרות ברירת המחדל של Query Explain
אפשר להשתמש בספריות הלקוח כדי לשלוח בקשה לאפשרות ברירת מחדל.
שימו לב שהבקשות מאומתות באמצעות IAM, עם אותן הרשאות של פעולות שאילתה רגילות. המערכת מתעלמת מטכניקות אימות אחרות, כמו Firebase Authentication. מידע נוסף זמין במדריך בנושא IAM לספריות לקוח של שרתים.
Java (אדמין)
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 של Query Explain
אפשר להשתמש בספריות הלקוח כדי לשלוח בקשה לאפשרות ניתוח.
שימו לב שהבקשות מאומתות באמצעות IAM, עם אותן הרשאות של פעולות שאילתה רגילות. המערכת מתעלמת מטכניקות אימות אחרות, כמו Firebase Authentication. מידע נוסף זמין במדריך בנושא IAM לספריות לקוח של שרתים.
Java (אדמין)
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;
בדוגמה הבאה מוצג האובייקט stats שמוחזר בנוסף לאובייקט planInfo.
הפורמט המדויק של התגובה תלוי בסביבת ההפעלה. התגובה לדוגמה היא בפורמט 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",
}
}
}מידע נוסף זמין במאמר הפניה לדוח Query Explain.
פירוש התוצאות וביצוע שינויים
נבחן תרחיש לדוגמה שבו אנחנו שולחים שאילתה לגבי סרטים לפי ז'אנר ומדינה שבה הם הופקו.
לדוגמה, נניח שיש שאילתת SQL ששווה ערך לזו.
SELECT * FROM /movies WHERE category = 'Romantic' AND country = 'USA';
אם נשתמש באפשרות הניתוח, המדדים שיוחזרו יראו שהשאילתה מופעלת על שני אינדקסים של שדה יחיד, (category ASC, __name__ ASC) ו-(country ASC, __name__ ASC). היא סורקת 16,500 רשומות אינדקס, אבל מחזירה רק 1,200 מסמכים.
// 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).
אם נריץ שוב את השאילתה עם האפשרות analyze, נוכל לראות שהאינדקס החדש שנוצר נבחר עבור השאילתה הזו, והיא רצה הרבה יותר מהר ויעיל.
// 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", } } }