אופטימיזציה של ביצועי השאילתות
כדי לפתור בעיות שקשורות לשאילתות איטיות, משתמשים בQuery Explain כדי לקבל את תוכנית הביצוע של השאילתה ואת פרופיל הביצוע בזמן הריצה. בקטע הבא מפורטים השלבים שאפשר לבצע כדי לשפר את ביצועי השאילתות, בהתאם לפרופיל הביצוע:
הגבלת מספר התוצאות
כדי לדעת אם השאילתה מחזירה הרבה מסמכים, בודקים את השדה 'רשומות שהוחזרו' בעץ הביצוע. כדאי להגביל את מספר המסמכים שמוחזרים באמצעות פסקה $limit. כך מצטמצם גודל הבייטים של התוצאות בסדרות, כשהן מוחזרות ללקוחות ברשת. במקרים שבהם הצומת Limit קודם לצומת MajorSort, מנוע השאילתות יכול לאחד את הצמתים Limit ו-MajorSort ולהחליף מימוש מלא בזיכרון ומיון במיון TopN, וכך להפחית את דרישת הזיכרון של השאילתה.
הגבלת גודל מסמך התוצאה
כדי להימנע מאחזור שדות לא נחוצים, כדאי להגביל את גודל המסמך שמוחזר באמצעות סעיף $project. כך אפשר לצמצם את עלויות החישוב והזיכרון של עיבוד תוצאות הביניים, ואת גודל הבייטים של התוצאות כשהן מוחזרות ללקוחות ברשת. במקרים שבהם כל השדות שאליהם מתייחסת השאילתה מכוסים על ידי אינדקס רגיל (לא אינדקס מרובה מפתחות), זה גם מאפשר לסריקת האינדקס לכסות את השאילתה באופן מלא, וכך לא צריך לאחזר מסמכים מהאחסון הראשי.
שימוש באינדקסים
כדי להגדיר אינדקסים ולבצע אופטימיזציה שלהם:
זיהוי אם השאילתה משתמשת באינדקס
כדי לזהות אם השאילתה משתמשת באינדקס, בודקים את צמתי העלה בעץ הביצוע. אם צומת העלה של עץ הביצוע הוא צומת TableScan, המשמעות היא שהשאילתה לא משתמשת באינדקס וסורקת מסמכים מהאחסון הראשי. אם נעשה שימוש באינדקס, צומת העלה של עץ הביצוע יציג את מזהה האינדקס ואת שדות האינדקס של האינדקס.
איך בודקים אם אפשר לבצע אופטימיזציה לאינדקס שבו נעשה שימוש
אינדקס שימושי לשאילתה אם הוא יכול להקטין את מספר המסמכים שמנוע השאילתות צריך לאחזר מהאחסון הראשי, או אם סדר השדות שלו יכול לספק את דרישת המיון של השאילתה.
אם נעשה שימוש באינדקס בשאילתה, אבל מנוע השאילתות עדיין מאחזר ומוחק הרבה מסמכים, כפי שמזוהה על ידי צומת סריקה שמחזיר הרבה רשומות ואחריו צומת סינון שמחזיר מעט רשומות, זה סימן לכך שפרדיקט השאילתה שמסופק באמצעות האינדקס לא סלקטיבי. כדי ליצור אינדקס מתאים יותר, אפשר לעיין במאמר יצירת אינדקסים.
אם נעשה שימוש באינדקס שאינו מרובה מפתחות בשאילתה, אבל מנוע השאילתות עדיין מבצע סידור מחדש בזיכרון של קבוצת התוצאות, כפי שמצוין על ידי צומת MajorSort בעץ הביצוע של השאילתה, זהו סימן לכך שאי אפשר להשתמש באינדקס כדי לספק את דרישת המיון של השאילתה. כדי ליצור אינדקס מתאים יותר, אפשר לעיין בקטע הבא.
אופטימיזציה של שאילתות $lookup
אפשר לבצע אופטימיזציה של שאילתות $lookup על ידי הוספת אינדקסים לאוסף from, וכך הפעולה יכולה למצוא ביעילות מסמכים תואמים בלי לסרוק את האוסף כולו.
$lookup עם localField ועם foreignField
אם אתם משתמשים באפשרויות localField ו-foreignField בשלב $lookup, צריך ליצור אינדקס ב-foreignField באוסף from.
$lookup עם צינורות עיבוד נתונים בתוך צינורות עיבוד נתונים
אם אתם משתמשים באפשרות pipeline בשלב $lookup עם $match שלבים, כדאי ליצור אינדקס בשדות שמשתתפים באוסף החיצוני כדי להימנע מסריקה מלאה של האוסף:
- בשלבים
$matchעם סמנטיקה של מסנן (לדוגמה,{$match: {a: true}}), יוצרים אינדקס בשדות שמשתתפים בקולקציה החיצונית (a). - בשלבי
$matchעם סמנטיקה של צבירה שמשווה שדה עם ערך קבוע (לדוגמה,{$match: {$expr: {$gt: [a, 10]}}}) או עם השוואות שוויון (eqאוin) בין שדות ומשתנים שמוגדרים ב-let(לדוגמה,{$match: {$expr: {$eq: [a, "$$a"]}}}), צריך ליצור אינדקס בשדות שמשתתפים באוסף החיצוני. שימו לב שהאינדקס עם כמה מפתחות לא ישמש בתכנון.
יצירת אינדקסים
פועלים לפי ההוראות בתיעוד בנושא ניהול אינדקסים כדי ליצור אינדקסים. כדי לוודא שהשאילתה יכולה להשתמש באינדקסים, צריך ליצור אינדקסים רגילים (לא Multikey) עם שדות בסדר הבא:
- כל השדות שישמשו באופרטורים של שוויון. כדי למקסם את הסיכוי לשימוש חוזר בשאילתות, צריך לסדר את השדות בסדר יורד לפי מספר הפעמים שהשדות מופיעים באופרטורים של שוויון בין שאילתות.
- כל השדות שייכללו במיון (באותו סדר).
- שדות שישמשו באופרטורים של טווח או אי-שוויון בסדר יורד של סלקטיביות אילוצי השאילתה.
- שדות שיוחזרו כחלק משאילתה באינדקס: הכללת שדות כאלה באינדקס מאפשרת לאינדקס לכסות את השאילתה ולמנוע את הצורך באחזור מסמך מהאחסון הראשי.
לשאילתות שכוללות סינון ומיון של שדות מערך, כדאי ליצור אינדקסים מרובי מפתחות.
שימוש ברמז לשאילתה
אם יצרתם אינדקס מתאים יותר לשאילתה, אבל מנוע השאילתות לא משתמש באינדקס הזה, אתם יכולים לבטל את העדפת האינדקס של מנוע השאילתות באמצעות רמז לשאילתה.