עבודה עם הטמעות וקטוריות (תצוגה מקדימה)

בדף הזה מוסבר איך ליצור אינטראקציה עם Cloud SQL כדי לבנות אפליקציות שמשתמשות בהטמעות וקטוריות.

‫Cloud SQL ל-MySQL תומך באחסון של הטמעות וקטוריות. לאחר מכן תוכלו ליצור אינדקסים של חיפוש וקטורי ולבצע חיפושים של דמיון בהטמעות הווקטוריות האלה, יחד עם שאר הנתונים שאתם מאחסנים ב-Cloud SQL.

אחסון של הטמעת וקטורים

אתם יכולים להשתמש ב-Cloud SQL ל-MySQL כדי לאחסן הטמעות וקטוריות על ידי יצירת עמודה של הטמעות וקטוריות בטבלה. המיפוי של עמודת ההטמעה של הווקטורים המיוחדים הוא לסוג הנתונים VARBINARY. בדומה לנתונים רלציוניים אחרים בטבלה, אפשר לגשת להטמעות וקטוריות בטבלה עם ערבויות טרנזקציונליות קיימות. טבלה עם עמודת הטבעת וקטור היא טבלת InnoDB רגילה, ולכן היא עומדת בדרישות של מאפייני האטומיוּת, העקביות, הבידוד והעמידות (ACID). המאפיינים של ACID חלים על כל הפעולות, למעט בדיקות באינדקס של חיפוש וקטורי.

כשמגדירים טבלה להטמעות וקטוריות, כדאי לקחת בחשבון את הנקודות הבאות:

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

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

  • אפשר לעיין גם ברשימת המגבלות.

השכפול פועל באותו אופן בעמודת הטמעת הווקטור כמו בעמודות אחרות של MySQL InnoDB.

‫Cloud SQL תומך בחיפוש דמיון באמצעות שאילתות חיפוש של K-nearest neighbor (KNN) ושל approximate nearest neighbor (ANN). אפשר להשתמש בשני סוגי החיפושים הווקטוריים במופעים של Cloud SQL. אפשר ליצור אינדקס של חיפוש וקטורי רק לחיפושי ANN.

‫Cloud SQL תומך בשאילתות באמצעות חיפוש וקטורי KNN, שנקרא גם חיפוש מדויק של השכן הקרוב ביותר. ביצוע חיפוש וקטורי של KNN מספק החזרה מושלמת. אתם יכולים לבצע חיפושי KNN בלי ליצור אינדקס חיפוש וקטורי. חיפוש KNN מבוסס על ביצוע אלגוריתם לסריקת טבלה.

בחיפוש KNN, ‏ Cloud SQL תומך גם בפונקציות הבאות לחיפוש מרחק בין וקטורים:

  • קוסינוס
  • מכפלה סקלרית
  • מרחק L2 בריבוע

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

ב-Cloud SQL אפשר ליצור שאילתות חיפוש ANN ולחפש באמצעותן על ידי יצירת אינדקסים של חיפוש וקטורי. אינדקס חיפוש וקטורי של ANN מאפשר לבצע אופטימיזציה לביצועים מהירים במקום לזכירה מושלמת. לחיפוש ANN,‏ Cloud SQL תומך בסוגי האינדקסים הבאים:

  • BRUTE_FORCE: סוג ברירת המחדל של אינדקס לחיפוש וקטורי לטבלת בסיס שיש בה פחות מ-10,000 שורות. הסוג הזה מתאים במיוחד לחיפושים בתוך קבוצת משנה קטנה יותר של קבוצת נתונים מקורית. הזיכרון שמשמש לאינדקס שווה לגודל של מערך הנתונים. סוג האינדקס הזה לא נשמר בדיסק.
  • TREE_SQ: סוג ברירת המחדל של אינדקס החיפוש הווקטורי לטבלת בסיס עם 10,000 שורות או יותר. הסוג הזה משתמש בכמות הזיכרון הכי קטנה, או בערך ב-25% מגודל מערך הנתונים. האינדקסים של TREE_SQ נשמרים בדיסק.
  • TREE_AH: סוג של אינדקס לחיפוש וקטורי שמספק אלגוריתם של סוג חיפוש גיבוב אסימטרי. כפי שמיושם ב-Cloud SQL, סוג האינדקס הזה לא מותאם לשימוש בזיכרון ולא נשמר.

עדכון אינדקסים של חיפוש וקטורי

‫Cloud SQL ל-MySQL מעדכן את האינדקסים של חיפוש וקטורים בזמן אמת. כל טרנזקציה שמבצעת פעולות של שפת טיפול בנתונים (DML) בטבלת הבסיס גם מעבירה שינויים לאינדקסים המשויכים של חיפוש וקטורי. השינויים באינדקס של חיפוש וקטורי גלויים באופן מיידי לכל שאר העסקאות, כלומר רמת הבידוד היא READ_UNCOMMITTED.

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

שכפול של אינדקסים של חיפוש וקטורי

‫Cloud SQL ל-MySQL משכפל אינדקסים של חיפוש וקטורי לכל העותקים לקריאה. אין תמיכה במסנני שכפול ובשכפול של אינדקסים של חיפוש וקטורי לשכפולים מדורגים.

הגדרת מופע לתמיכה בהטמעות וקטוריות

בקטע הזה מוסבר איך להגדיר את מכונת Cloud SQL כך שתתמוך באחסון, באינדוקס ובשאילתות של הטמעות וקטוריות.

גם מופעים של מהדורת Cloud SQL Enterprise וגם מופעים של מהדורת Cloud SQL Enterprise Plus תומכים בהטמעות וקטוריות.

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

הפעלת הטמעות וקטוריות

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

gcloud sql instances patch INSTANCE_NAME \
  --database-flags=FLAGS

מחליפים את INSTANCE_NAME בשם המכונה שבה רוצים להפעיל תמיכה בהטמעת וקטורים.

ב-FLAGS, מגדירים את הדגלים הבאים של MySQL במכונה:

  • cloudsql_vector: מגדירים את הדגל הזה לערך on כדי להפעיל אחסון של הטמעת וקטורים ותמיכה בחיפוש. אפשר ליצור במכונה עמודות חדשות של הטמעת וקטורים ואינדקסים של חיפוש וקטורים.
  • cloudsql_vector_max_mem_size: אופציונלי. מציינים את הקצאת הזיכרון המקסימלית בבייטים לכל האינדקסים של חיפוש וקטורים במופע. אם לא מציינים את הדגל הזה, הקצאת הזיכרון שמוגדרת כברירת מחדל היא 1GB, שזו הקצאת הזיכרון המינימלית. למידע נוסף על חישוב הכמות שצריך לציין, אפשר לעיין במאמר בנושא הגדרת הקצאת הזיכרון לאינדקסים של חיפוש וקטורי.

    הזיכרון הייעודי הזה מגיע מהזיכרון שהוקצה ל-innodb_buffer_pool_size. מאגר הזיכרון הזמין שלכם יצטמצם באותו סכום. הערך המקסימלי המותר לסימון הזה הוא 50% מהסכום הכולל של innodb_buffer_pool_size.

    אם מציינים ערך שגדול מ-50% מהנפח הכולל של innodb_buffer_pool_size, ‏ Cloud SQL מקטין את הערך האפקטיבי ל-50% מהנפח הזמין ורושם הודעת אזהרה לגבי המכונה.

אחרי שמגדירים את הדגלים, הפקודה עשויה להיראות כך:

gcloud sql instances patch my-instance \
  --database-flags=cloudsql_vector=on,cloudsql_vector_max_mem_size=4294967296

הדגלים להגדרת התמיכה בהטמעות וקטוריות ב-Cloud SQL ל-MySQL הם דגלים סטטיים. אחרי שמעדכנים את המכונה באמצעות הדגלים, היא מופעלת מחדש באופן אוטומטי כדי שהשינויים בהגדרות ייכנסו לתוקף.

מידע נוסף על הגדרת דגלים של מסד נתונים ב-MySQL זמין במאמר הגדרת דגלים של מסד נתונים.

השבתת הטמעות וקטורים

כדי להשבית הטמעות וקטוריות, מגדירים את הדגל cloudsql_vector לערך off.

לדוגמה:

gcloud sql instances patch INSTANCE_NAME \
  --database-flags=cloudsql_vector=off

מחליפים את INSTANCE_NAME בשם המכונה שבה רוצים להשבית את התמיכה בהטמעת וקטורים.

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

אחרי ההפעלה מחדש של המכונה, Cloud SQL ל-MySQL מבצע את הפעולות הבאות:

  • הסרת כל האינדקסים של חיפוש וקטורי TREE_SQ שנשמרו מהדיסק הקשיח.
  • שומר את הרשומות בטבלת מילון הנתונים של אינדקסים של חיפוש וקטורי שנבנו. עם זאת, ב-Cloud SQL ל-MySQL לא מתבצעת בנייה מחדש של האינדקסים, וכל שאילתת חיפוש באינדקסים האלה מחזירה שגיאה.
  • ממשיך לאחסן את הטמעות הווקטור בטבלאות הבסיס. הטמעות וקטוריות עדיין נגישות.

אם תפעילו מחדש את הדגל cloudsql_vector עבור המכונה, ‏ Cloud SQL ינסה לבנות מחדש את האינדקסים בזמן שהמכונה תופעל מחדש על סמך הרשומות בטבלת מילון הנתונים.

קריאת ההגדרה של העותק לקריאה בלבד

אם המכונה עומדת בקריטריונים של גרסת התחזוקה והפעלת הדגל, ‏ Cloud SQL תומך באופן מלא בהטמעות וקטוריות ברפליקה לקריאה.

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

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

אין תמיכה באינדקסים של חיפוש וקטורי בשכפול מדורג.

דוגמה: אינדקס ושאילתה של חיפוש וקטורי ב-ANN

בדוגמה הבאה מוסבר איך ליצור שאילתה ואינדקס לחיפוש וקטורי מבוסס-ANN ב-Cloud SQL.

  1. ליצור הטמעות וקטוריות. אפשר ליצור הטמעות וקטוריות באופן ידני או להשתמש ב-API להטמעת טקסט לפי בחירתכם. דוגמה לשימוש ב-Vertex AI זמינה במאמר יצירת הטמעות וקטוריות על סמך נתונים בשורות.

  2. יוצרים טבלה ב-Cloud SQL ל-MySQL שמכילה עמודה של הטמעת וקטור עם שלושה ממדים.

    CREATE TABLE books (
    id   INTEGER PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(60),
    embedding VECTOR(3) USING VARBINARY
    );
    
  3. מוסיפים הטמעת וקטורים לעמודה.

    INSERT INTO books VALUES (
    1,
    'book title',
     string_to_vector('[1,2,3]')
    );
    
  4. שומרים את השינויים.

    commit;
    
  5. יוצרים את אינדקס החיפוש הווקטורי. אם יוצרים אינדקס TREE_SQ או TREE_AH, הטבלה צריכה לכלול לפחות 1,000 שורות.

    CALL mysql.create_vector_index('vectorIndex',
                                   'dbname.books',
                                   'embedding',
                                   'index_type=BRUTE_FORCE, distance_measure=L2_SQUARED'
                                   );
    
  6. קבלת השכנים הקרובים ביותר.

    SELECT title FROM books
    WHERE
    NEAREST(embedding) TO (string_to_vector('[1,2,3]'));
    

יצירת הטמעות וקטוריות על סמך נתוני שורות

אפשר ליצור הטמעת וקטורים לנתונים בשורה מסוימת באמצעות API להטמעת טקסט, כמו Vertex AI או OpenAI. אפשר להשתמש בכל API להטמעת טקסט עם הטמעות וקטוריות של Cloud SQL. עם זאת, צריך להשתמש באותו API להטמעת טקסט כדי ליצור את הווקטור של מחרוזת השאילתה. אי אפשר לשלב בין ממשקי API שונים כדי לקבל נתוני מקור ווקטוריזציה של שאילתות.

לדוגמה, אפשר ליצור הטבעת וקטור מ-Vertex AI:

from vertexai.language_models import TextEmbeddingModel

def text_embedding() -> list:
    """Text embedding with a Large Language Model."""
    model = TextEmbeddingModel.from_pretrained("text-embedding-004")
    embeddings = model.get_embeddings(["What is life?"])
    for embedding in embeddings:
        vector = embedding.values
        print(f"Length of Embedding Vector: {len(vector)}")
    return vector

if __name__ == "__main__":
    text_embedding()

אחסון הטמעות וקטוריות

בקטע הזה מובאות דוגמאות להצהרות לאחסון הטמעות וקטוריות ב-Cloud SQL.

יצירת טבלה חדשה עם עמודה של הטמעת וקטור

CREATE TABLE books (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(60),
  embedding VECTOR(3) USING VARBINARY
  );

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

ALTER TABLE books
ADD COLUMN embedding
VECTOR(3) USING VARBINARY;

הוספת הטמעת וקטורים

INSERT INTO books (
  title,
  embedding
  ) VALUES (
    'book title',
    string_to_vector('[1,2,3]')
);

הוספה של כמה הטמעות וקטוריות

INSERT INTO books (
  title,
  embedding
  ) VALUES (
    'book title',
    string_to_vector('[1,2,3]')),
     ('book title', string_to_vector('[4,5,6]')
);

פעולת Upsert של הטמעת וקטור

INSERT INTO books (
  id,
  title,
  embedding
  ) VALUES (
    1,
    'book title',
     string_to_vector('[1,2,3]')
     )
ON DUPLICATE KEY UPDATE embedding = string_to_vector('[1,2,3]');

עדכון הטמעת וקטורים

UPDATE books
SET embedding = string_to_vector('[1,2,3]')
WHERE id = 1;

מחיקה של הטמעת וקטורים

DELETE FROM books
WHERE embedding = string_to_vector('[1,2,3]');

עבודה עם אינדקסים של חיפוש וקטורי

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

המלצות

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

  • לפני שיוצרים אינדקס של חיפוש וקטורי, צריך לטעון נתונים לטבלה. טבלת הבסיס צריכה לכלול לפחות 1,000 שורות. הדרישות האלה חלות רק על סוגי אינדקס החיפוש TREE_SQ ו-TREE_AH. אם יש לכם יותר נקודות נתונים זמינות, תוכלו לבצע חלוקה טובה יותר למחיצות ולאמן את האינדקס בצורה טובה יותר.
  • מעקב אחרי השימוש בזיכרון של האינדקסים. אם ייגמר הזיכרון של המופע, לא תוכלו ליצור או לבנות אינדקסים. במקרה של אינדקסים קיימים, אחרי שמגיעים לסף, Cloud SQL כותב אזהרות ביומן השגיאות של MySQL באופן תקופתי. אפשר לראות את השימוש בזיכרון בטבלה information_schema.innodb_vector_indexes.
  • אם בוצעו שינויים משמעותיים בשפת DML בטבלת הבסיס, צריך לבנות מחדש את האינדקסים של חיפוש הווקטורים. כדי לקבל את הגודל ההתחלתי של האינדקס בזמן הבנייה ואת הגודל הנוכחי של האינדקס, שולחים שאילתה לטבלה information_schema.innodb_vector_indexes.
  • בדרך כלל, אפשר להשאיר את מספר המחיצות לחישוב פנימי. אם יש לכם תרחיש שימוש שבו אתם רוצים לציין את מספר המחיצות, אתם צריכים שיהיו לכם לפחות 100 נקודות נתונים לכל מחיצה.

טבלת בסיס לקריאה בלבד במהלך פעולות אינדקס של חיפוש וקטורי

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

התמדה, כיבוי והשפעה על תחזוקה

רק אינדקסים של חיפוש וקטורי מסוג TREE_SQ נשמרים בדיסק במהלך כיבוי נקי של מכונה. אינדקסים של חיפוש וקטורי שמשתמשים בסוגים TREE_AH ו-BRUTE_FORCE הם רק בזיכרון.

אחרי כיבוי נקי של מכונה, Cloud SQL טוען מחדש את האינדקסים של חיפוש וקטורים כשהמכונה מופעלת מחדש. עם זאת, אחרי קריסה או כיבוי לא תקין,‏ Cloud SQL צריך לבנות מחדש את האינדקסים של חיפוש וקטורי. לדוגמה, בכל פעם שהמופע שלכם עובר קריסה ושחזור מגיבוי ושחזור, שחזור מערכת מנקודה מסוימת בזמן (PITR) או יתירות כשל בזמינות גבוהה (HA),‏ Cloud SQL בונה מחדש את אינדקסים של חיפוש וקטורי. באירועים האלה, קורה הדבר הבא:

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

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

הגדרת הקצאת הזיכרון לאינדקסים של חיפוש וקטורי

‫Cloud SQL יוצר ומנהל אינדקסים של חיפוש וקטורי בזיכרון. סוג האינדקס TREE_SQ נשמר בהשבתה נקייה ונטען מחדש אחרי הפעלה מחדש של המופע. במהלך זמן הריצה, כל האינדקסים של חיפוש וקטורי צריכים להישאר בזיכרון.

כדי לוודא שיש מספיק זיכרון ב-Cloud SQL כדי לשמור את כל האינדקסים של חיפוש וקטורי בזיכרון, צריך להגדיר את מכונת Cloud SQL באמצעות cloudsql_vector_max_mem_size דגל מסד נתונים. cloudsql_vector_max_mem_size קובעת כמה זיכרון המכונה של Cloud SQL מקצה לאינדקסים של חיפוש וקטורי. כשמגדירים את הערך של הדגל, חשוב לזכור את הנקודות הבאות:

  • ערך ברירת המחדל והערך המינימלי הוא 1GB. המגבלה העליונה היא 50% מגודל מאגר הנתונים.
  • אחרי שמגדירים את הדגל הזה, המכונה מופעלת מחדש באופן אוטומטי כדי ששינוי ההגדרה ייכנס לתוקף.
  • אם נעשה שימוש בכל הזיכרון שהוגדר במופע, לא תוכלו ליצור או לשנות מדדי חיפוש וקטוריים.

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

gcloud sql instances patch INSTANCE_NAME \
  --database-flags= cloudsql_vector_max_mem_size=NEW_MEMORY_VALUE

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

  • INSTANCE_NAME: השם של המכונה שבה משנים את הקצאת הזיכרון.
  • NEW_MEMORY_VALUE: הקצאת הזיכרון המעודכנת, בבייטים, לאינדקסים של חיפוש וקטורי.

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

חישוב הזיכרון הנדרש

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

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

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

dataset_size = <num_embeddings> * (4 * <dimensions>)

לדוגמה, אם יש לכם מיליון הטמעות של 768 מימדים, הערך של dataset_size הוא 3GB.

על סמך הדוגמה הקודמת, דרישות הזיכרון לסוגים השונים של אינדקסים הן:

סוג האינדקס זיכרון זמן בנייה זיכרון האינדקס
TREE_SQ ‫4GB ‎1GB
TREE_AH ‫3.5GB ‫3.5GB
BRUTE_FORCE ‫3GB ‫3GB

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

בכל פעם שמתבצעות פעולות DML בטבלת הבסיס שבה מוטמעים הווקטורים, מתבצע עדכון של אינדקס חיפוש הווקטורים בזמן אמת. העדכונים האלה משנים את הזיכרון שבשימוש של האינדקס, שיכול להתכווץ או להתרחב בהתאם לפעולת ה-DML. אפשר לעקוב אחרי הזיכרון שבשימוש של אינדקס באמצעות שאילתה בטבלה information_schema.innodb_vector_indexes. למידע על מעקב אחרי הגודל של אינדקס Vector Search, אפשר לעיין במאמר בנושא מעקב אחרי אינדקסים של Vector Search.

יצירת אינדקס של חיפוש וקטורי

התחביר של ההצהרה ליצירת אינדקס לחיפוש וקטורי הוא:

CALL mysql.create_vector_index('INDEX_NAME',
                                'DB_NAME.TABLE_NAME',
                                'COLUMN_NAME',
                                'PARAMETERS'
                              );

לדוגמה:

CALL mysql.create_vector_index('vectorIndex',
                                'db.books',
                                'embedding',
                                'index_type=TREE_SQ, distance_measure=l2_squared'
                               );

השם של האינדקס שאתם מציינים חייב להיות ייחודי במסד הנתונים.

פרמטרים של אינדקס לחיפוש וקטורי

הפונקציות mysql.create_vector_index ו-mysql.alter_vector_index תומכות בכמה פרמטרים שאפשר לציין באמצעות צמדי מפתח/ערך שמופרדים בפסיקים. כל הפרמטרים של הפונקציה mysql.create_vector_index הם אופציונליים. אם מציינים מחרוזת ריקה או NULL, ערכי ברירת המחדל של הפרמטרים מוגדרים לאינדקס.

  • distance_measure: הערכים הנתמכים הם: L2_SQUARED,‏ COSINE ו-DOT_PRODUCT. ברירת המחדל היא L2_SQUARED.
  • num_neighbors: מספר השכנים שיוחזרו משאילתת ANN. אפשר גם לשנות את הפרמטר הזה כשמבצעים את שאילתת החיפוש. ערך ברירת המחדל הוא 10.
  • index_type: מציין את סוג האינדקס שייבנה. הערכים התקפים הם: BRUTE_FORCE,‏ TREE_SQ ו-TREE_AH.

    • BRUTE_FORCE הוא ברירת המחדל לטבלה עם פחות מ-10,000 שורות
    • TREE_SQ הוא ברירת המחדל לטבלה עם 10,000 שורות או יותר

    כדי לציין את סוג האינדקס TREE_AH או TREE_SQ, גודל טבלת הבסיס צריך להיות גדול מ-1,000 שורות.

  • num_parititions: מציין את מספר האשכולות של K-means שייבנו. מותר להשתמש בפרמטר הזה רק אם הגדרתם index_type. האפשרות הזו לא רלוונטית ל-BRUTE_FORCE. אם מציינים את סוג האינדקס TREE_SQ או TREE_AH, הגודל של טבלת הבסיס צריך להיות גדול מ-num_partitions * 100 או שווה לו.

שינוי אינדקס של חיפוש וקטורי

CALL mysql.alter_vector_index('DB_NAME.INDEX_NAME', 'PARAMETERS');

הפונקציה alter_vector_index משמשת באופן מפורש לבנייה מחדש של אינדקס של חיפוש וקטורי. כדי להשתמש בפונקציה הזו, האינדקס צריך כבר להתקיים. כדאי לבנות מחדש אינדקס בתרחישי השימוש הבאים:

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

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

אינדקס וקטורי קיים זמין במהלך הפעולה alter_vector_index. עדיין אפשר להריץ שאילתות חיפוש באינדקס.

הסרת אינדקס של חיפוש וקטורי

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

CALL mysql.drop_vector_index('DB_NAME.INDEX_NAME');

שאילתות של הטמעות וקטוריות

בקטע הזה מובאות דוגמאות לדרכים שונות לשאילתות של הטמעות וקטוריות.

הצגת הטמעות הווקטורים

SELECT vector_to_string(embedding) FROM books;

קבלת חיפוש מדויק של וקטורים שכנים להטמעת וקטורים

SELECT id,cosine_distance(embedding,
   string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY dist
LIMIT 10;

קבלת חיפוש משוער של שכנים להטמעת וקטורים

SELECT title FROM books
WHERE
NEAREST(embedding) TO (string_to_vector('[1,2,3]'), 'num_neighbors=10');

ביצוע חיפוש ANN תומך בשני פרמטרים. שניהם אופציונליים.

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

סינון הטמעות וקטורים

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

SELECT title FROM books
WHERE
NEAREST(embedding) TO (string_to_vector('[1,2,3]'))
AND printyear > 1991;

שאילתה לגבי המרחק של הטמעת וקטור

בקטע הזה מפורטות דוגמאות לפונקציות של מרחק וקטורי שזמינות לחיפוש KNN.

חישוב מרחק הקוסינוס

SELECT cosine_distance(embedding, string_to_vector('[3,1,2]'))
AS distance FROM books WHERE id=10;

קבלת המרחק של מכפלה סקלרית

SELECT dot_product(embedding, string_to_vector('[3,1,2]'))
AS distance FROM books WHERE id=10;

קבלת המרחק בריבוע L2

SELECT l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
AS distance FROM books WHERE id=10;

קבלת שורות במרחק מסוים

SELECT * FROM books
WHERE l2_squared_distance(embedding, string_to_vector('[1,2,3]')) < 10;

אפשר לשלב עם ORDER BY ועם LIMIT

SELECT id, vector_to_string(embedding),
       l2_squared_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books ORDER BY dist LIMIT 10;

מעקב אחרי אינדקסים של חיפוש וקטורי

כדי לקבל מידע בזמן אמת על כל האינדקסים של חיפוש וקטורי במופע, משתמשים בטבלה information_schema.innodb_vector_indexes.

כדי לראות את הטבלה, מריצים את הפקודה הבאה:

SELECT * FROM information_schema.innodb_vector_indexes;

פלט לדוגמה:

*************************** 1. row ***************************
       INDEX_NAME: test.t4_index
       TABLE_NAME: test.t4_bf
       INDEX_TYPE: BRUTE_FORCE
     DIST_MEASURE: SquaredL2Distance
           STATUS: Ready
            STATE: INDEX_READY_TO_USE
       PARTITIONS: 0
SEARCH_PARTITIONS: 0
     INITIAL_SIZE: 40000
     CURRENT_SIZE: 40000
          QUERIES: 0
        MUTATIONS: 0
     INDEX_MEMORY: 160000
   DATASET_MEMORY: 0

בטבלה information_schema.innodb_vector_indexes אפשר לראות את הפרטים הבאים:

  • האפשרויות שעשויות להיווצר. במילים אחרות, num_partitions או מספר המחיצות שיש לבדוק בשאילתה.
  • בעמודות STATE ו-STATUS מוצג המצב הנוכחי של האינדקס. במהלך שלב הבנייה, בעמודה 'סטטוס' מופיע מידע על התקדמות הבנייה של אינדקס החיפוש הווקטורי.
  • העמודה INITIAL_SIZE מספקת את גודל הטבלה במהלך יצירת האינדקס. אפשר להשוות את הגודל הזה לערך CURRENT_SIZE כדי לקבל מושג לגבי מידת השינוי באינדקס מאז שהוא נוצר, בגלל פקודות DML בטבלת הבסיס.
  • בעמודות QUERIES ו-MUTATIONS מוצגות תובנות בזמן אמת לגבי רמת העומס באינדקס.
  • העמודות INDEX_MEMORY ו-DATASET_MEMORY מספקות מידע על צריכת הזיכרון של האינדקס. ‫INDEX_MEMORY מציין כמה זיכרון נצרך על ידי האינדקס, ו-DATASET_MEMORY מציין כמה זיכרון נוסף נצרך במהלך משך זמן של תהליך build.

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

כדי לראות את הטבלה, מריצים את הפקודה הבאה:

SELECT * FROM mysql.vector_indexes;

פלט לדוגמה:

*************************** 1. row ***************************
   index_name: test.index1
   table_name: test.t1
  column_name: j
index_options: index_type=BRUTE_FORCE, distance_measure=L2_SQUARED
       status: ACTIVE
  create_time: 2024-04-08 22:46:21
  update_time: 2024-04-08 22:46:21
1 row in set (0.00 sec)

מגבלות

  1. כל טבלה יכולה לכלול רק עמודה אחת של הטבעת וקטור.
  2. לכל טבלה יכול להיות רק אינדקס אחד של חיפוש וקטורי.
  3. הטמעה וקטורית יכולה לכלול עד 16,000 ממדים.
  4. אין תמיכה בחלוקה למחיצות ברמת הטבלה ב-InnoDB בטבלאות עם עמודות של הטמעת וקטורים.
  5. אם המכונה מופעלת מחדש לאחר כיבוי לא תקין, מערכת Cloud SQL בונה מחדש את אינדקס החיפוש הווקטורי באופן אוטומטי.
    1. במהלך הבנייה מחדש של אינדקס החיפוש הווקטורי, טבלת הבסיס היא לקריאה בלבד.
    2. אם Cloud SQL לא מצליח לקבל נעילה בטבלה בתוך הזמן שצוין, יכול להיות שהבנייה האוטומטית מחדש של האינדקס תיכשל.
    3. אם בנייה אוטומטית מחדש של האינדקס נכשלת, צריך לבנות מחדש את האינדקס באופן ידני.
  6. כדי להוסיף עמודה של הטבעת וקטור, לטבלה צריך להיות מפתח ראשי. ‫Cloud SQL לא תומך במפתחות ראשיים מהסוגים BIT, BINARY, VARBINARY, JSON, BLOB, TEXT או בסוגי נתונים מרחביים. מפתחות ראשיים מורכבים לא יכולים לכלול אף אחד מהסוגים האלה.
  7. אם יש אינדקס של חיפוש וקטורי בטבלה, אי אפשר לבצע פעולות DDL. צריך להסיר את אינדקס החיפוש הווקטורי לפני שמבצעים פעולות DDL בטבלת הבסיס.
  8. אין תמיכה בהטמעות של וקטורים בטבלאות שאינן מסוג InnoDB או בטבלאות זמניות.
  9. עמודת הטמעת וקטורים לא יכולה להיות עמודה שנוצרה.
  10. אפשר לשלב את פרדיקט NEAREST..TO עם פרדיקטים סקלריים אחרים באמצעות AND או OR. הערכת הפרדיקטים הסקלריים בטבלה מתבצעת אחרי החלת הפרדיקטים הווקטוריים.
  11. הפרדיקט NEAREST..TO נתמך רק בהצהרת SELECT. אין תמיכה ב-NEAREST..TO בהצהרות DML אחרות.
  12. אין תמיכה בשאילתות משנה ב-NEAREST..TO. אי אפשר להוסיף אילוץ למפתח הראשי של טבלת הבסיס אם קיים אינדקס של חיפוש וקטורי.
  13. אפשר לבצע סינון מראש רק באמצעות פונקציות מרחק ושימוש ב-ORDER BY עם LIMIT.

    לדוגמה, אם יוצרים את הטבלה הבאה:

    CREATE TABLE books
    (
    bookid          INT PRIMARY KEY,
    title           VARCHAR(1000),
    author          VARCHAR(100),
    printyear       int,
    country         VARCHAR(100),
    bvector         VECTOR(1536) USING VARBINARY
    //bvector is embedding vector of book's plot,genre,reviews etc
    );
    

    אז אפשר להשתמש בשאילתה הבאה כדי לבצע סינון מראש.

    //select query to obtain books by specific author and having similar plot-genre-reviews
    SELECT bookid, title, author,l2_squared_distance(bvector, qvector) dist
    FROM books where author='cloudsql' ORDER BY dist LIMIT 10
    

    אפשר להשתמש בסינון אחרי ההמרה עם הפונקציות NEAREST..TO ופונקציות המרחק.

פתרון בעיות

במקרה של קריסה, האינדקס נבנה מחדש באופן אוטומטי. במהלך בנייה מחדש, יש שתי הגבלות:

  1. במהלך יצירת האינדקס, טבלת הבסיס נמצאת במצב קריאה-בלבד.
  2. במהלך הבנייה מחדש של האינדקס, שאילתות ANN מול אינדקסים קיימים נכשלות.

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