כדי לפתור בעיות של שאילתות איטיות, אפשר להשתמש ב-Query Explain כדי לקבל את תוכנית ההרצה של השאילתה ואת פרופיל ההרצה בזמן הריצה. בקטע הבא מתוארים השלבים שאפשר לבצע כדי לשפר את ביצועי השאילתות, בהתאם לפרופיל הביצוע:
להגביל את מספר התוצאות
כדי לזהות אם השאילתה מחזירה הרבה מסמכים, אפשר להשתמש בשדה records returned בעץ הביצוע. כדי להגביל את מספר המסמכים שמוחזרים, כדאי להשתמש בשלב limit(...). כך מצמצמים את גודל הבייטים של התוצאות בסדרה כשהן מוחזרות ללקוחות דרך הרשת. במקרים שבהם הצומת Limit מופיע לפני הצומת MajorSort, מנוע השאילתות יכול לאחד את הצמתים Limit ו-MajorSort ולהחליף את מיון החומר המלא בזיכרון במיון TopN, וכך להפחית את דרישות הזיכרון של השאילתה.
הגבלת גודל המסמך של התוצאה
כדי להגביל את גודל המסמך שמוחזר, כדאי להשתמש ב-select(...) כדי להחזיר רק את השדות הנדרשים, או ב-remove_fields(...) כדי למחוק שדות גדולים מדי. כך אפשר להפחית את עלות המחשוב והזיכרון של עיבוד תוצאות הביניים ואת גודל הבייטים של התוצאות בסדרה כשהן מוחזרות ללקוחות דרך הרשת. במקרים שבהם כל השדות שמוזכרים בשאילתה מכוסים על ידי אינדקס רגיל, השאילתה יכולה להיות מכוסה באופן מלא על ידי סריקת האינדקס, בלי צורך לאחזר מסמכים מהאחסון הראשי.
שימוש באינדקסים
כך מגדירים אינדקסים ומבצעים אופטימיזציה שלהם.
איך בודקים אם השאילתה משתמשת באינדקס
כדי לזהות אם השאילתה משתמשת באינדקס, אפשר לבדוק את צומתי העלים בעץ הביצוע. אם צומת העלה של עץ ההפעלה הוא צומת TableScan, המשמעות היא שהשאילתה לא משתמשת באינדקס וסורקת מסמכים מהאחסון הראשי. אם נעשה שימוש באינדקס, צומת העלה של עץ הביצוע יציג את מזהה האינדקס ואת שדות האינדקס של האינדקס.
זיהוי מדד טוב יותר
אינדקס שימושי לשאילתה אם הוא יכול להפחית את מספר המסמכים שמנוע השאילתות צריך לאחזר מהאחסון הראשי, או אם סדר השדות שלו יכול לספק את דרישת המיון של השאילתה.
אם נעשה שימוש באינדקס לשאילתה, אבל מנוע השאילתות עדיין מאחזר ומוחק מסמכים רבים, כפי שזוהה על ידי צומת סריקה שמחזיר רשומות רבות ואחריו צומת סינון שמחזיר מעט רשומות, זה סימן לכך שהפרדיקט של השאילתה שסופק באמצעות האינדקס אינו סלקטיבי. כדי ליצור אינדקס מתאים יותר, קראו את המאמר יצירת אינדקסים.
אם נעשה שימוש באינדקס לשאילתה, אבל מנוע השאילתות עדיין מבצע סידור מחדש בזיכרון של קבוצת התוצאות, כפי שזוהה על ידי צומת MajorSort בעץ הביצוע של השאילתה, זה סימן שלא ניתן להשתמש באינדקס שנעשה בו שימוש כדי לספק את דרישת המיון של השאילתה. כדי ליצור אינדקס מתאים יותר, עיינו בקטע הבא.
יצירת אינדקסים
כדי ליצור אינדקסים, פועלים לפי ההוראות במסמכי התיעוד בנושא ניהול אינדקסים. כדי לוודא שהשאילתה יכולה להשתמש באינדקסים, צריך ליצור אינדקסים רגילים (לא עם כמה מפתחות) עם שדות בסדר הבא:
- כל השדות שישמשו באופרטורים של שוויון. כדי למקסם את הסיכוי לשימוש חוזר בשאילתות, כדאי לסדר את השדות בסדר יורד של הופעת השדות באופרטורים של שוויון בין שאילתות.
- כל השדות שלפיהם יתבצע המיון (באותו סדר).
- שדות שישמשו באופרטורים של טווח או אי-שוויון, בסדר יורד של סלקטיביות האילוצים בשאילתה.
- שדות שיוחזרו כחלק משאילתה באינדקס: הכללת שדות כאלה באינדקס מאפשרת לאינדקס לכסות את השאילתה, וכך לא צריך לאחזר את המסמך מהאחסון הראשי.
אילוץ סריקה של אינדקס או טבלה
כששולחים שאילתה ל-Cloud Firestore, המערכת משתמשת באופן אוטומטי בכל האינדקסים שיכולים לייעל את השאילתה. לכן לא צריך לציין אינדקס לשאילתות. עם זאת, בשאילתות שחשובות לעומס העבודה, מומלץ להשתמש באפשרות forceIndex כדי לקבל ביצועים עקביים יותר.
במקרים מסוימים, יכול להיות ש-Cloud Firestore יבחר אינדקס שיגרום לעלייה בזמן האחזור של השאילתה. אם ביצעתם את השלבים לפתרון בעיות של רגרסיות בביצועים, והגעתם למסקנה שכדאי לנסות אינדקס אחר לשאילתה, אתם יכולים לציין את האינדקס באמצעות האפשרות forceIndex.
אפשר להשתמש באפשרות forceIndex בכל שלב של קלט בפעולות של Pipeline כדי לשנות את תוכנית לביצוע שאילתה של Cloud Firestore שמוגדרת כברירת מחדל ולציין אינדקס לשימוש, או כדי לאלץ סריקת טבלה.
אילוץ אינדקס ספציפי
כדי לאלץ את השאילתה להשתמש באינדקס ספציפי, צריך לספק את מזהה האינדקס כמחרוזת לאפשרות forceIndex. מזהה האינדקס מופיע במסוף או בהודעות השגיאה.
בדוגמה הבאה, מתכנן השאילתות נאלץ להשתמש באינדקס עם המזהה CICAgOi36pgK:
Node.js
// Force Planner to use Index ID CICAgOi36pgK await db.pipeline() .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" }) .limit(100) .execute();
Java
// Force Planner to use Index ID CICAgOi36pgK Pipeline.Snapshot results1 = firestore.pipeline() .collectionGroup("customers", new CollectionGroupOptions() .withHints(new CollectionHints().withForceIndex("CICAgOi36pgK"))) .limit(100) .execute().get();
המשך
// Force Planner to use Index ID CICAgOi36pgK snapshot1 := client.Pipeline(). CollectionGroup("customers", firestore.WithForceIndex("CICAgOi36pgK")). Limit(100). Execute(ctx)
הנה כמה תרחישים לדוגמה שבהם כדאי לאלץ אינדקס ספציפי:
- בדיקת הביצועים של אינדקסים שונים.
- כדי להבטיח ששאילתה תשתמש באינדקס ספציפי שידוע כאופטימלי.
- ביטול האופטימיזציה כשהבחירה שמוגדרת כברירת מחדל לא אופטימלית לשאילתה מסוימת.
אם האינדקס שצוין לא נמצא, השאילתה נכשלת.
אילוץ סריקת טבלה
בסריקת טבלה, המערכת קוראת מסמכים באוסף או בקבוצת האוספים בלי להשתמש באינדקסים משניים. כדי לאלץ סריקת טבלה, מגדירים את forceIndex ל-primary.
בדוגמה הבאה, סריקת הטבלה נכפית:
// Force Planner to only do a Full-Table Scan
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "primary" })
.limit(100)
אפשר להשתמש בסריקת טבלה במקרים הבאים:
- לאוספים קטנים מאוד, שבהם התקורה של האינדקס לא מוצדקת.
- לשאילתות שניגשות לרוב המסמכים באוסף.
- לניפוי באגים ולהשוואת ביצועים.
שימוש ב-forceIndex עם Query Explain
אתם יכולים להשתמש בהסבר על שאילתות במצבים explain או analyze כדי לבחון את ההשפעות של forceIndex:
- כדי לוודא ש-Cloud Firestore השתמש באינדקס שצוין ב-
forceIndex, בודקים את צומתי העלים של עץ הביצוע של מזהה האינדקס. - מוודאים שצומת
TableScanמופיע בתוכנית כשמשתמשים ב-forceIndex: "primary". - במצב
analyze, משווים בין מדדי הביצועים – כמו זמן אחזור, מסמכים שנסרקו ורשומות אינדקס שנסרקו – עם ובליforceIndexכדי לשפר את ביצועי השאילתות.
שיטות מומלצות להשגת היעד forceIndex
למרות ש-forceIndex מספק יותר שליטה על הרצת השאילתות, הכלי לאופטימיזציה של שאילתות ב-Cloud Firestore בדרך כלל יעיל לרוב תרחישי השימוש.
כדאי לפעול לפי השיטות המומלצות הבאות כשמשתמשים ב-forceIndex:
- השתמשו ב-
forceIndexבזהירות. אם הביצועים של תוכנית ברירת המחדל לביצוע שאילתות לא אופטימליים, השתמשו בהסבר על שאילתות כדי לאבחן את הבעיה לפני שתאלצו שימוש באינדקס. - כשמשתמשים ב-
forceIndex, חשוב לבדוק את השאילתות עם נפחי נתונים מציאותיים כדי להבין את מאפייני הביצועים והעלות שלהן. - מומלץ להימנע משימוש ב-
forceIndex: "primary"באוספים גדולים בסביבות ייצור.
למידע נוסף על הפלט של שאילתה שבוצעה באמצעות Query Explain, ראו הפניית ביצוע שאילתה.