יצירת אינדקס של IVF

אינדקסים של קובץ הפוך (IVF) ב-AlloyDB ל-PostgreSQL מאפשרים להאיץ חיפושים של דמיון וקטורי בהטמעות מאוחסנות עם הרבה ממדים, באמצעות קוונטיזציה סקלרית. אתם יכולים ליצור אינדקסים מסוג IVF באמצעות התוסף vector כדי להפחית את השימוש בזיכרון ולהאיץ שאילתות של וקטורים עם עד 8,000 מאפיינים. מידע נוסף על אחסון הטמעות זמין במאמר אחסון הטמעות וקטורים.

לפני שמתחילים

לפני שמתחילים ליצור אינדקסים, צריך לבצע את הפעולות הבאות.

  • וקטורי ההטמעה מתווספים לטבלה במסד הנתונים של AlloyDB.

  • גרסה 0.5.0 ומעלה של התוסף vector, שמבוסס על pgvector ונוסף על ידי Google ל-AlloyDB, מותקנת.

    CREATE EXTENSION IF NOT EXISTS vector;
    

יצירת אינדקס IVF

‫pgvector תומך בחיפוש השכן הקרוב ביותר (ANN) באמצעות הוספה לאינדקס. ב-AlloyDB יש תכונה נוספת של קוונטיזציה סקלרית, שאפשר לציין כשיוצרים אינדקס. כשהתכונה מופעלת, קוונטיזציה סקלרית יכולה להאיץ באופן משמעותי שאילתות עם וקטורים בעלי ממדים גדולים יותר, ומאפשרת לאחסן וקטורים עם עד 8,000 ממדים.

כדי להפעיל קוונטיזציה סקלרית באינדקס שמבוסס על pgvector, צריך לציין את IVF כשיטת האינדקס ואת SQ8 כקוונטיזטור:

CREATE INDEX INDEX_NAME ON TABLE
  USING ivf (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (lists = LIST_COUNT, quantizer = 'QUANTIZER');

מחליפים את מה שכתוב בשדות הבאים:

  • ‫INDEX_NAME: שם האינדקס שרוצים ליצור, לדוגמה my-ivf-index. שמות האינדקסים משותפים במסד הנתונים. חשוב לוודא שכל שם אינדקס הוא ייחודי לכל טבלה במסד הנתונים.

  • ‫TABLE: הטבלה שאליה רוצים להוסיף את האינדקס.

  • ‫EMBEDDING_COLUMN: עמודה שבה מאוחסנים נתוני vector.

  • ‫DISTANCE_FUNCTION: פונקציית המרחק שבה משתמשים באינדקס הזה. צריך לבחור אחת מהאפשרויות:

    • מרחק L2: vector_l2_ops

    • מכפלה פנימית: vector_ip_ops

    • מרחק קוסינוס: vector_cosine_ops

  • ‫LIST_COUNT: מספר הרשימות שבהן צריך להשתמש עם האינדקס הזה. למידע נוסף על אופן ההחלטה לגבי הערך הזה, ראו כוונון של אינדקס IVF.

  • ‫QUANTIZER: סוג ה-quantizer שבו רוצים להשתמש.

    מגדירים אחת מהאפשרויות הבאות:

    • ‫SQ8: מומלץ. תגובה מהירה יותר לשאילתות ותמיכה בווקטורים עם עד 8,000 מאפיינים, אבל עם אובדן מסוים של שליפה, שלא משפיע על תרחישי ייצור.

    • ‫FLAT: תגובה איטית יותר לשאילתות, שימוש רב יותר בזיכרון ותמיכה בווקטורים עם עד 2,000 מאפיינים, אבל יכול להיות אובדן זניח של שליפה.

    כדי ליצור את האינדקס הזה בעמודת הטמעה שמשתמשת בסוג הנתונים real[] במקום ב-vector, צריך להמיר את העמודה לסוג הנתונים vector:

CREATE INDEX INDEX_NAME ON TABLE
  USING ivf ((CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS))) DISTANCE_FUNCTION)
  WITH (lists = LIST_COUNT, quantizer = 'SQ8');

מחליפים את DIMENSIONS ברוחב הממדי של עמודת ההטמעה. למידע נוסף על איך למצוא את המאפיינים, עיינו בפונקציה vector_dims בפונקציות וקטוריות.

כדי לראות את התקדמות ההוספה לאינדקס, משתמשים בתצוגה pg_stat_progress_create_index:

SELECT * FROM pg_stat_progress_create_index;

בעמודה phase מוצג המצב הנוכחי של יצירת האינדקס, והשלב building postings מציין שיצירת האינדקס קרובה לסיום.

כדי לכוונן את האינדקס לאיזון בין השליפה ל-QPS, קראו את המאמר כוונון אינדקס IVF.

הרצת שאילתה

אחרי שמאחסנים את ההטמעות במסד הנתונים ומוסיפים אותן לאינדקס, אפשר להתחיל לשלוח שאילתות באמצעות פונקציונליות השאילתות של pgvector.

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

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY 'EMBEDDING'
    LIMIT ROW_COUNT;

מחליפים את מה שכתוב בשדות הבאים:

  • ‫TABLE: הטבלה שמכילה את ההטמעה שאליה משווים את הטקסט.

  • ‫EMBEDDING_COLUMN: העמודה שמכילה את ההטמעות השמורות.

  • ‫DISTANCE_FUNCTION_QUERY: פונקציית המרחק שבה משתמשים בשאילתה הזו. בוחרים אחת מהאפשרויות הבאות, בהתאם לפונקציית המרחק שבה השתמשתם כשנוצר האינדקס:

    • מרחק L2: <->

    • מכפלה פנימית: <#>

    • מרחק קוסינוס: <=>

  • ‫EMBEDDING: וקטור ההטמעה שרוצים למצוא את השכנים הסמנטיים הקרובים ביותר שלו.

  • ‫ROW_COUNT: מספר השורות שיוחזרו.

    מציינים 1 אם רוצים רק את ההתאמה הטובה ביותר.

למידע נוסף על דוגמאות אחרות לשאילתות, ראו שאילתות.

אפשר גם להשתמש בפונקציה embedding() כדי להמיר את הטקסט לווקטור. מחילים את הווקטור על אחד מהאופרטורים של pgvector השכן הקרוב ביותר, <-> למרחק L2, כדי למצוא את שורות מסד הנתונים עם ההטמעות הכי דומות מבחינה סמנטית.

מכיוון שהפונקציה embedding() מחזירה מערך real, צריך להמיר באופן מפורש את הקריאה ל-embedding() ל-vector כדי להשתמש בערכים האלה עם אופרטורים של pgvector.

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