כוונון האינדקסים של Scalable Nearest Neighbors (ScaNN) ב-AlloyDB ל-PostgreSQL עוזר לאזן בין שליפת החיפוש לבין שאילתות לשנייה (QPS) בעומסי העבודה של הווקטורים. הפרמטרים והערכים המומלצים להגדרה תלויים בשימוש באינדקס ScaNN עם שתי רמות, שלוש רמות או ארבע רמות.
מגבלות
הפרמטר num_leaves קובע את מספר המחיצות באינדקס. מספר המחיצות המקסימלי המותר הוא:
- 100 מיליון ל-PostgreSQL מגרסה 17 ואילך.
- 30 מיליון ל-PostgreSQL בגרסה 16 ומטה.
אינדקס עץ דו-שלבי
כדי ליישם המלצות שיעזרו לכם למצוא את הערכים האופטימליים של num_leaves ו-num_leaves_to_search למערך הנתונים, בצעו את השלבים המומלצים הבאים:
- כדי ליצור את האינדקס
ScaNNשמותאם למקרים הבאים, מגדירים את הפרמטרnum_leavesלערך הבא, כאשר rows הוא מספר השורות בטבלה שנוסף לה אינדקס:- זמן בניית אינדקס ואיכות מאוזנים מגדירים את
num_leavesלערךsqrt(rows). - quality: מגדירים את num_leaves ל-rows/100.
- זמן בניית אינדקס ואיכות מאוזנים מגדירים את
- מריצים את שאילתות הבדיקה ומגדילים את הערך של
scann.num_leaves_to_search(אוscann.pct_leaves_to_search) עד שמגיעים לטווח ה-recall הרצוי, למשל 95%. מידע נוסף על ניתוח השאילתות זמין במאמר ניתוח השאילתות. - שימו לב ליחס בין
scann.num_leaves_to_searchל-num_leaves, כי תצטרכו להשתמש בו בשלבים הבאים. היחס הזה מספק קירוב של מערך הנתונים שיעזור לכם להשיג את ה-recall הרצוי.
אם אתם עובדים עם וקטורים בעלי ממדים גבוהים (500 ממדים או יותר) ורוצים לשפר את ה-recall, נסו לשנות את הערך שלscann.pre_reordering_num_neighbors. ערך ברירת המחדל הוא50 * K, כאשרKהוא המגבלה שהגדרתם בשאילתה. - אם מספר השאילתות לשנייה נמוך מדי אחרי שהשאילתות מגיעות ליעד ה-recall, פועלים לפי השלבים הבאים:
- יוצרים מחדש את האינדקס ומגדילים את הערך של
num_leavesו-scann.num_leaves_to_searchלפי ההנחיות הבאות:- מגדירים את
num_leavesלגורם גדול יותר של השורש הריבועי של מספר השורות. לדוגמה, אם הערך שלnum_leavesבאינדקס מוגדר לשורש הריבועי של מספר השורות, נסו להגדיר אותו לפי 2 מהשורש הריבועי. אם הערך כבר כפול, נסו להגדיר אותו לשורש ריבועי משולש. - מגדילים את
scann.num_leaves_to_searchלפי הצורך כדי לשמור על היחס שלו עםnum_leaves, שציינתם בשלב 3. - מגדירים את
num_leavesלערך שקטן או שווה למספר השורות חלקי 100.
- מגדירים את
- מריצים שוב את שאילתות הבדיקה.
בזמן הרצת שאילתות הבדיקה, נסו להקטין את
scann.num_leaves_to_searchכדי למצוא ערך שמגדיל את QPS תוך שמירה על שיעור גבוה של recall. אפשר לנסות ערכים שונים שלscann.num_leaves_to_searchבלי לבנות מחדש את האינדקס.
- יוצרים מחדש את האינדקס ומגדילים את הערך של
- חוזרים על שלב 4 עד שגם ה-QPS וגם טווח ה-recall מגיעים לערכים קבילים.
אינדקס עץ תלת-שלבי
בנוסף להמלצות לגבי אינדקס ScaNN של עץ דו-רמתי, כדאי לפעול לפי ההנחיות הבאות.
כדי ליישם המלצות למציאת הערך האופטימלי של הפרמטרים num_leaves ו-max_num_levels, פועלים לפי השלבים הבאים:
יוצרים את האינדקס
ScaNNעם השילובים הבאים שלnum_leavesו-max_num_levels, בהתאם ליעדי הביצועים:- איזון בין זמן היצירה של האינדקס לבין האיכות: מגדירים את
max_num_levelsכ-2ואתnum_leavesכ-power(rows, ⅔). - אופטימיזציה לאיכות: מגדירים את
max_num_levelsכ-2ואתnum_leavesכ-rows/100.
- איזון בין זמן היצירה של האינדקס לבין האיכות: מגדירים את
מריצים את שאילתות הבדיקה. מידע נוסף על ניתוח שאילתות זמין במאמר ניתוח השאילתות.
שימו לב ליחס בין
scann.num_leaves_to_searchל-num_leaves, שבו תשתמשו בשלבים הבאים. היחס הזה מספק הערכה לגבי קבוצת הנתונים שתעזור לכם להשיג את שיעור ההחזרה (recall) הרצוי.
אם אתם עובדים עם וקטורים בעלי ממדים גבוהים (500 ממדים או יותר) ורוצים לשפר את ה-recall, נסו לשנות את הערך של scann.pre_reordering_num_neighbors. ערך ברירת המחדל הוא 50 * K, כאשר K הוא המגבלה שהגדרתם בשאילתה.
אם מספר השאילתות לשנייה נמוך מדי אחרי שהשאילתות מגיעות ליעד ה-recall, פועלים לפי השלבים הבאים:
- יוצרים מחדש את האינדקס ומגדילים את הערך של
num_leavesו-scann.num_leaves_to_searchלפי ההנחיות הבאות: - מגדירים את
num_leavesלגורם גדול יותר שלpower(rows, ⅔). לדוגמה, אם באינדקס מוגדרnum_leavesל-power(rows, ⅔), נסו להגדיר אותו לכפול מ-power(rows, ⅔). אם הערך כבר כפול, נסו להגדיר אותו כפי 3 מהערך שלpower(rows, ⅔). - מגדילים את
scann.num_leaves_to_searchלפי הצורך כדי לשמור על היחס שלו עםnum_leaves, שציינתם בשלב 3. - צריך להגדיר את
num_leavesלערך שקטן מ-rows/100או שווה לו. - מריצים שוב את שאילתות הבדיקה. בזמן הרצת שאילתות הבדיקה, נסו להקטין את
scann.num_leaves_to_searchכדי למצוא ערך שמגדיל את QPS תוך שמירה על שיעור גבוה של recall. אפשר לנסות ערכים שונים שלscann.num_leaves_to_searchבלי לבנות מחדש את האינדקס.
- יוצרים מחדש את האינדקס ומגדילים את הערך של
חוזרים על שלב 4 עד שגם ה-QPS וגם טווח ה-recall מגיעים לערכים קבילים.
אינדקס עץ עם ארבע רמות
בנוסף להמלצות לגבי אינדקסים של עץ עם שלוש רמות, כדאי להשתמש בהנחיות הבאות כדי למצוא את הערך האופטימלי ל-num_leaves ול-max_num_levels:
יוצרים אינדקס ScaNN עם השילובים הבאים של
num_leavesו-max_num_levels, בהתאם ליעדי הביצועים:איזון בין זמן היצירה של האינדקס לבין האיכות: מגדירים את
max_num_levelsכ-3ואתnum_leavesכ-power(ROWS, 3/4).אופטימיזציה לאיכות: מגדירים את
max_num_levelsלערך3ואתnum_leavesלערךROWS/100.
מריצים את שאילתות הבדיקה. למידע נוסף על ניתוח שאילתות, קראו את המאמר ניתוח שאילתות.
שימו לב ליחס בין
scann.num_leaves_to_searchלביןnum_leaves. אתם משתמשים ביחס הזה כדי להשיג את יעד ה-recall בשלבים הבאים.אם אתם עובדים עם וקטורים בעלי ממדים גבוהים (500 ממדים או יותר) ורוצים לשפר את ה-recall, נסו לשנות את הערך של
scann.pre_reordering_num_neighbors.אם ה-QPS נמוך מדי אחרי שהשאילתות מגיעות ליעד ה-recall, צריך ליצור מחדש את האינדקס ולהגדיל את הערכים של
num_leavesו-scann.num_leaves_to_searchלפי ההנחיות הבאות:צריך להגדיר את
num_leavesלגורם גדול יותר שלpower(ROWS, 3/4). לדוגמה, אם הערך שלnum_leavesבאינדקס מוגדר ל-power(ROWS, 3/4), נסו להגדיר אותו לערך כפול. אם הערך כבר כפול, נסו להגדיר אותו כמשולש.מגדילים את
scann.num_leaves_to_searchלפי הצורך כדי לשמור על היחס שלו עםnum_leaves, שציינתם בשלב השלישי.מגדירים את
num_leavesלערך שקטן מ-ROWS/100או שווה לו.מריצים שוב את שאילתות הבדיקה. בזמן שאתם מריצים את שאילתות הבדיקה, נסו להקטין את
scann.num_leaves_to_search. צריך למצוא ערך שמגדיל את QPS תוך שמירה על שיעור גבוה של recall. נסו ערכים שונים שלscann.num_leaves_to_searchבלי לבנות מחדש את האינדקס.
חוזרים על שלב 4 עד שטווח ה-Recall וה-QPS מגיעים לערכים קבילים.
שיפור הזיכרון בחיפושים מסוננים
כשמבצעים חיפוש וקטורי של k-nearest neighbor (KNN) שכולל מסנן, יכול להיות שהשאילתה תחזיר פחות תוצאות ממה שביקשתם בסעיף LIMIT. זה יכול להוביל למצב שנקרא אחזור לא מספיק, וסביר יותר שזה יקרה כשמשתמשים במסננים מאוד סלקטיביים. זה קורה כי המחיצות הראשוניות, או העלים, ש-ScaNN מחפש לא מכילים מספיק וקטורים שעומדים בתנאי הסינון.
כדי לפתור את הבעיה הזו, ב-AlloyDB יש תכונה שמאפשרת להרחיב את החיפוש באופן דינמי מעבר לקבוצת העלים הראשונית, כדי למצוא מספיק תוצאות תואמות.
איך הסטרימינג עובד
כדי להפעיל את פונקציונליות הסטרימינג, מגדירים את הפרמטר scann.satisfy_limit לערך relaxed_order. כשהאפשרות הזו מופעלת, הסריקה הווקטורית ממשיכה לחפש במחיצות עלים נוספות עד שהיא מוצאת מספיק תוצאות כדי לעמוד בדרישות של LIMIT בשאילתה, וכך משפרת את ה-recall.
כדי למנוע מהחיפוש להימשך יותר מדי זמן ולשלוט בהשפעה על הביצועים, משתמשים בפרמטר scann.max_num_leaves_to_search_pct. ההגדרה הזו קובעת את הגבול העליון של אחוז העלים הכולל ששאילתה יכולה לבקר בהם. ערך ברירת המחדל הוא 15%.
מתי להשתמש בסטרימינג
כדאי להשתמש בתכונת הסטרימינג במקרים הבאים:
- אתם משתמשים במסננים בחיפושים הווקטוריים.
- השאילתות מחזירות פחות תוצאות מהצפוי על סמך משפט ה-
LIMIT.
כדי לשפר את השליפה של החיפושים המסוננים, צריך להפעיל את scann.satisfy_limit. מומלץ להגדיר את scann.max_num_leaves_to_search_pct כדי להגיע לאיזון בין השליפה לבין ביצועי השאילתה.
אופטימיזציה של הביצועים של שאילתות מסוננות
כדי לקבל ביצועים אופטימליים בשאילתות מסוננות, מומלץ ליצור אינדקס B-tree בעמודות המסוננות. כך הכלי לתכנון שאילתות יכול לבחור את אסטרטגיית הסינון היעילה ביותר ולקצר משמעותית את זמן הרצת השאילתה.
תחזוקת אינדקסים
אם הטבלה שלכם נוטה להתעדכן או להתווסף לעיתים קרובות, מומלץ להוסיף מחדש לאינדקס את האינדקס הקיים של ScaNN כדי לשפר את דיוק השליפה.
אתם יכולים לעקוב אחרי מדדי האינדקס כדי לראות שינויים בהתפלגויות של וקטורים או במוטציות של וקטורים מאז שהאינדקס נוצר, ואז להוסיף אותם לאינדקס מחדש בהתאם. מידע נוסף על מדדים זמין במאמר הצגת מדדים של אינדקס וקטורי.