מה זה אינדקס במסד נתונים - האנלוגיה שסוף סוף תבהיר לכם את זה¶
אם אי פעם כתבתם שאילתת SQL שרצה על טבלה גדולה ולקחה חמש שניות במקום עשרים מילישניות, ואז מישהו אמר לכם "תוסיפו אינדקס" והשאילתה פתאום טסה, ואתם לא ממש הבנתם למה - הפוסט הזה בדיוק בשבילכם.
האנלוגיה שמסבירה הכל¶
תדמיינו ספר עב כרס בן 800 עמודים בלי תוכן עניינים ובלי אינדקס בסוף. עכשיו מישהו מבקש מכם למצוא כל מקום בספר שבו מוזכרת המילה "פילוסופיה". אין לכם ברירה, אתם חייבים לדפדף עמוד אחר עמוד, מההתחלה ועד הסוף, ולבדוק כל אחד. זה נקרא סריקה מלאה, וזה בדיוק מה שמסד נתונים עושה כשאין לו אינדקס - הוא עובר שורה אחר שורה על כל הטבלה כדי למצוא את מה שביקשתם.
עכשיו תדמיינו שיש בסוף הספר אינדקס מסודר - "פילוסופיה: עמודים 45, 112, 340". במקום לדפדף את כל הספר, אתם קופצים ישר לעמודים הרלוונטיים. זה בדיוק מה שאינדקס במסד נתונים עושה - הוא מבנה נתונים נוסף שמאורגן כך שאפשר למצוא ערך ספציפי מהר בלי לסרוק את כל הטבלה.
איך זה עובד מבפנים, בלי להיכנס עמוק מדי¶
ברוב המסדי נתונים, אינדקס בנוי על מבנה נתונים שנקרא עץ מאוזן (B-Tree). זה בעצם עץ שממויין, שבו כל שלב מצמצם את מרחב החיפוש בערך בחצי. במקום לבדוק מיליון שורות אחת-אחת, מנוע מסד הנתונים "יורד" בעץ בכמה קפיצות בלבד ומגיע ישר לתשובה. זו הסיבה שחיפוש עם אינדקס יכול להיות מהיר פי אלפים על טבלה גדולה.
בפועל, יצירת אינדקס נראית כך:
מהרגע הזה, כל שאילתה שמחפשת לקוח לפי אימייל תשתמש באינדקס הזה במקום לסרוק את כל הטבלה.
אז למה לא לשים אינדקס על כל עמודה?¶
זו בדיוק השאלה שמפרידה בין מי שמבין אינדקסים לבין מי שרק שמע עליהם. אינדקס לא בא בחינם.
- הוא תופס מקום אחסון נוסף, כי הוא בעצם מבנה נתונים נפרד שמוחזק לצד הטבלה.
- הוא מאט כתיבה. בכל פעם שמוסיפים, מעדכנים או מוחקים שורה, מנוע מסד הנתונים צריך לעדכן גם את האינדקס, לא רק את הטבלה. טבלה עם עשרה אינדקסים תהיה איטית משמעותית בכתיבה מטבלה בלי אינדקסים.
לכן ההחלטה איפה לשים אינדקס היא איזון. שמים אינדקס על עמודות שמחפשים בהן הרבה - כמו מפתחות זרים, עמודות שמסננים לפיהן בתדירות גבוהה (WHERE), או עמודות שממיינים לפיהן (ORDER BY). לא שמים אינדקס על עמודות שכמעט אף פעם לא מחפשים בהן.
הטעות הכי נפוצה של מתחילים¶
מתכנתים מתחילים נוטים לשים אינדקס על כל עמודה "ליתר ביטחון", וזה בדיוק הפוך ממה שנכון. הטעות השנייה הכי נפוצה היא לא לשים אינדקס בכלל, ואז לגלות אחרי חצי שנה שהאפליקציה "פתאום" נהיית איטית - בפועל היא לא הייתה איטית פתאום, היא פשוט הגיעה לכמות נתונים שבה סריקה מלאה כבר מורגשת.
הכלל האצבע הכי חשוב הוא הכי פשוט: אם עמודה מופיעה הרבה בתנאי WHERE או ב-JOIN, סביר שהיא מועמדת טובה לאינדקס. תמיד אפשר לבדוק את זה בפועל עם פקודת EXPLAIN, שמראה בדיוק איך מנוע מסד הנתונים מתכנן להריץ שאילתה, כולל אם הוא משתמש באינדקס או סורק את כל הטבלה.
למה זה נושא שכל מתכנת חייב להבין¶
ביצועים איטיים במסד נתונים הם אחת הסיבות הכי נפוצות לאפליקציות שקורסות תחת עומס. הבנה בסיסית של אינדקסים היא ההבדל בין מפתח שמזהה בעיית ביצועים תוך דקה, לבין מישהו שמנסה לפתור אותה על ידי הוספת עוד שרתים במקום לתקן שאילתה אחת בעייתית.
בקורס צד-שרת עוברים גם על נושא הביצועים הזה בפועל, כולל איך לזהות שאילתות איטיות ואיך לתקן אותן.
נתקעתם עם שאילתה שלא רוצה לרוץ מהר? זה בדיוק סוג הדבר שכיף לפתור ביחד בקהילה.