שיטות מומלצות לכוונון אינדקסים של ScaNN ב-AlloyDB ל-PostgreSQL

הפרמטרים המומלצים לאינדקס ScaNN משתנים בהתאם לבחירה שלכם אם ליצור אינדקס של עץ עם שתי רמות או שלוש רמות. בדף הזה מפורטות המלצות לאופטימיזציה של פרמטרים של אינדקסים ב-AlloyDB ל-PostgreSQL, כדי להשיג איזון אופטימלי בין היזכרות לבין QPS.

יצירת אינדקסים ב-ScaNN

מידע נוסף זמין במאמר בנושא הפניה לאינדקס ScaNN.

אינדקס עץ דו-רמתי

כדי ליישם המלצות שיעזרו לכם למצוא את הערכים האופטימליים של num_leaves ושל num_leaves_to_search עבור מערך הנתונים שלכם, פועלים לפי השלבים המומלצים הבאים:

  1. כדי ליצור את האינדקס ScaNN שממוטב למקרים הבאים, מגדירים את הפרמטר num_leaves לערך הבא, כאשר rows הוא מספר השורות בטבלה המאונדקסת:
    • balanced index build time and quality set num_leaves to sqrt(rows).
    • quality‏ num_leaves מוגדר כ-rows/100.
  2. מריצים את שאילתות הבדיקה, ומגדילים את הערך של scann.num_of_leaves_to_search, עד שמגיעים לטווח היעד של הזיכרון – למשל, 95%. מידע נוסף על ניתוח השאילתות זמין במאמר ניתוח השאילתות.
  3. חשוב לשים לב ליחס בין scann.num_leaves_to_search לבין num_leaves, שבו תשתמשו בשלבים הבאים. היחס הזה מספק קירוב לגבי מערך הנתונים שיעזור לכם להשיג את יעד ההחזרה.

    אם אתם עובדים עם וקטורים של מימדים גבוהים (500 מימדים ומעלה) ורוצים לשפר את ההחזרה, נסו לשנות את הערך של scann.pre_reordering_num_neighbors. ערך ברירת המחדל מוגדר לערך 50 * K, כאשר K הוא המגבלה שהגדרתם בשאילתה.
  4. אם ערך השאילתות לשנייה נמוך מדי אחרי שהשאילתות משיגות את ערך ההחזרה (recall) הרצוי, צריך לבצע את השלבים הבאים:
    1. יוצרים מחדש את האינדקס, ומגדילים את הערכים של num_leaves ושל scann.num_leaves_to_search בהתאם להנחיות הבאות:
      • מגדירים את num_leaves לגורם גדול יותר של השורש הריבועי של מספר השורות. לדוגמה, אם האינדקס num_leaves מוגדר לשורש הריבועי של מספר השורות, נסו להגדיר אותו כפול משורש הריבועי. אם הערך כבר הוכפל, נסו להגדיר אותו כערך משולש של השורש הריבועי.
      • מגדילים את scann.num_leaves_to_search לפי הצורך כדי לשמור על היחס שלו עם num_leaves, שרשמתם בשלב 3.
      • מגדירים את num_leaves לערך שקטן ממספר השורות חלקי 100 או שווה לו.
    2. מריצים שוב את שאילתות הבדיקה. במהלך הרצת שאילתות הבדיקה, כדאי להתנסות בהפחתת scann.num_leaves_to_search, כדי למצוא ערך שמגדיל את QPS תוך שמירה על ערך גבוה של recall. כדאי לנסות ערכים שונים של scann.num_leaves_to_search בלי לבנות מחדש את האינדקס.
  5. חוזרים על שלב 4 עד שגם ה-QPS וגם טווח ההחזרה מגיעים לערכים מקובלים.

אינדקס עץ עם שלוש רמות

בנוסף להמלצות לגבי אינדקס של עץ עם שתי רמות ScaNN, כדאי לפעול לפי ההנחיות הבאות.

כדי ליישם המלצות ולמצוא את הערך האופטימלי של פרמטרים של אינדקס num_leaves ו-max_num_levels, פועלים לפי השלבים הבאים:

  1. יוצרים את אינדקס ScaNN עם השילובים הבאים של num_leaves ו-max_num_levels בהתאם ליעדי הביצועים:

    • זמן בניית אינדקס האיזון ואיכותו: מגדירים את max_num_levels כ-2 ואת num_leaves כ-power(rows, ⅔).
    • אופטימיזציה לאיכות: מגדירים את max_num_levels כ-2 ואת num_leaves כ-rows/100.
  2. מריצים את שאילתות הבדיקה. מידע נוסף על ניתוח שאילתות זמין במאמר ניתוח השאילתות.

  3. חשוב לשים לב ליחס בין scann.num_leaves_to_search ל-num_leaves, שבו תשתמשו בשלבים הבאים. היחס הזה מספק קירוב לגבי מערך הנתונים שיעזור לכם להשיג את יעד ההיזכרות.

אם אתם עובדים עם וקטורים של מאפיינים גבוהים (500 מאפיינים ומעלה) ורוצים לשפר את ההחזרה, כדאי לנסות לשנות את הערך של scann.pre_reordering_num_neighbors. ערך ברירת המחדל מוגדר לערך 50 * K, כאשר K הוא המגבלה שהגדרתם בשאילתה.

  1. אם ערך ה-QPS נמוך מדי אחרי שהשאילתות משיגות את ערך הזיכרון (recall) הרצוי, צריך לפעול לפי השלבים הבאים:

    • יוצרים מחדש את האינדקס, ומגדילים את הערכים של num_leaves ו-scann.num_leaves_to_search בהתאם להנחיות הבאות:
    • מגדירים את num_leaves כגורם גדול יותר של power(rows, ⅔). לדוגמה, אם הערך של num_leaves באינדקס מוגדר ל-power(rows, ⅔), נסו להגדיר אותו לערך כפול מ-power(rows, ⅔). אם הערך כבר הוכפל, נסו להגדיר אותו כערך משולש של 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 בלי לבנות מחדש את האינדקס.
  2. חוזרים על שלב 4 עד שגם ה-QPS וגם טווח ההחזרה מגיעים לערכים מקובלים.

שיפור יכולת השליפה של תוצאות חיפוש מסוננות

כשמבצעים חיפוש וקטורי של k-nearest neighbor ‏ (KNN) שכולל מסנן, יכול להיות שהשאילתה תחזיר פחות תוצאות מהמספר שצוין בסעיף LIMIT. מצב כזה עלול להוביל למה שנקרא היזכרות לא מספקת, והוא סביר יותר כשמשתמשים במסננים סלקטיביים מאוד. זה קורה כי המחיצות הראשוניות, או העלים, ש-ScaNN מחפש בהן לא מכילות מספיק וקטורים שעומדים בתנאי הסינון.

כדי לפתור את הבעיה הזו, ב-AlloyDB יש תכונה שמאפשרת להרחיב את החיפוש באופן דינמי מעבר לקבוצת העלים הראשונית, כדי למצוא מספיק תוצאות תואמות.

איך סטרימינג עובד

כדי להפעיל את פונקציית הסטרימינג, צריך להגדיר את הפרמטר scann.satisfy_limit לערך relaxed_order. כשהתכונה הזו מופעלת, הסריקה הווקטורית ממשיכה לחפש במחיצות עלים נוספות עד שהיא מוצאת מספיק תוצאות כדי לענות על LIMIT של השאילתה, וכך משפרת את ההחזרה.

כדי למנוע מצב שבו החיפוש נמשך יותר מדי זמן ולשלוט בהשפעה על הביצועים, אפשר להשתמש בפרמטר scann.max_pct_leaves_to_search. ההגדרה הזו משמשת כאמצעי הגנה, כי היא מגדירה גבול עליון לאחוז העלים הכולל שאפשר לבקר בהם בשאילתה. ערך ברירת המחדל הוא 15%.

מתי כדאי להשתמש בסטרימינג

כדאי להשתמש בתכונת הסטרימינג במקרים הבאים:

  • אתם משתמשים במסננים עם חיפושי הווקטורים.
  • השאילתות מחזירות פחות תוצאות מהצפוי על סמך סעיף LIMIT.

אם מפעילים את scann.satisfy_limit, אפשר לשפר את ההחזרה של תוצאות החיפוש המסוננות. מומלץ גם להגדיר את scann.max_pct_leaves_to_search כדי להגיע לאיזון בין היזכרות לבין ביצועי שאילתות.

תחזוקת האינדקס

אם הטבלה שלכם נוטה להתעדכן או להשתנות לעיתים קרובות, מומלץ ליצור מחדש את האינדקס הקיים ScaNN באופן תקופתי כדי לשפר את דיוק האחזור. אתם יכולים לעקוב אחרי מדדי האינדקס כדי לראות שינויים בהתפלגויות הווקטורים או במוטציות הווקטורים מאז בניית האינדקס, ואז לבצע אינדוקס מחדש בהתאם. מידע נוסף על מדדים זמין במאמר הצגת מדדים של אינדקס וקטורי.

המאמרים הבאים