חיפוש וסינון באמצעות הטמעות וקטוריות

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

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

מפעילים את הדגל לניהול מסד הנתונים cloudsql_vector במכונה של Cloud SQL.

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

חיפוש השכנים הקרובים ביותר (ANN)

כדי לבצע חיפוש ANN, משתמשים בפונקציה approx_distance בסעיפים SELECT ו-ORDER BY. בחיפוש ANN צריך להשתמש בסעיף LIMIT. אפשר גם לקבל את ערך המרחק על ידי הוספת approx_distance לרשימה SELECT.

משתמשים בתחביר הבא לשאילתות ANN:

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
  approx_distance(
    embedding_name,
    string_to_vector('[1,2,3]'),
    'distance_measure=cosine,num_leaves_to_search=3')
    dist
FROM table
ORDER BY dist
LIMIT limit_value;

הפונקציה approx_distance משתמשת באפשרויות הבאות:

  • ‫embedding: משתמש בשם העמודה של הטמעת הווקטורים ממסד הנתונים הטבלאי.
  • ‫string_to_vector או vector_to_string: ממירה וקטור למחרוזת ומחרוזת לווקטור כדי שהווקטור יהיה קריא לאנשים.
  • ‫distance_measure: מציינים את מידת המרחק שבה רוצים להשתמש בחיפוש דמיון וקטורי. הערך הזה צריך להיות זהה לערך שהגדרתם בפרמטר distance_measure כשיצרתם את האינדקס. חובה לכלול את הפרמטר הזה. הערכים האפשריים של הפרמטר הזה הם:
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • ‫num_leaves_to_search: אופציונלי. מציין את מספר העלים שצריך לבדוק בחיפוש דמיון וקטורי של ANN. אם לא מציינים את מספר העלים, Cloud SQL משתמש בערך שנוצר על סמך גודל הטבלה, מספר העלים באינדקס הווקטורי וגורמים אחרים. אפשר לראות את הערך הזה בinformation_schema.innodb_vector_indexes. מומלץ לשנות את הערך של num_leaves_to_search כדי להגיע לאיזון הטוב ביותר בין איכות החיפוש לבין הביצועים של עומס העבודה הספציפי. אם מגדילים את הערך, הביצועים מושפעים אבל ה-recall משתפר.

בדוגמה הבאה מוסבר איך להשתמש ב-approx_distance כדי למצוא את K השורות הכי קרובות באמצעות מדד המרחק l2_squared, ולסדר את התוצאות לפי המרחק.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
                         'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
    approx_distance
        (embedding, string_to_vector('[1,2,3]'),
         'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;

סינון תוצאות משאילתות approx_distance

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

לדוגמה, בשאילתה הבאה:

SELECT id FROM products WHERE price < 100
ORDER BY approx_distance(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

הפונקציה approx_distance מחזירה את 11 השכנים הקרובים ביותר לווקטור השאילתה, בלי קשר למחיר. בסינון לאחר השאילתה, נבחרים המוצרים שהמחיר שלהם קטן מ-100. יכול להיות שלכל השכנים הקרובים ביותר יש מחיר < 100, ולכן יש 11 תוצאות לשאילתה. לחלופין, אם לאף אחד מהשכנים הקרובים ביותר אין מחיר < 100, לא יוחזרו שורות.

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

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

שימוש בסינון איטרטיבי כדי להגדיל את תוצאות החיפוש של ANN

אתם יכולים להשתמש בסינון איטרטיבי כשמסנני הבחירה של משפט ה-WHERE בשאילתת החיפוש של ANN מניבים פחות תוצאות ממספר התוצאות שצוין במשפט ה-LIMIT.

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

EXPLAIN FORMAT=TREE
SELECT * FROM t1 WHERE next_id BETWEEN 15 AND 100
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 10;

EXPLAIN
-> Limit: 10 row(s)  (rows=10)
   -> Vector index loop with iterative filtering
      -> Vector index scan on t1
      -> Filter: (t1.next_id between 15 and 100)
         -> Single-row index lookup on t1 using PRIMARY (id=t1.id)

אתם מאחזרים עוד שכנים מאינדקס וקטור החיפוש באופן איטרטיבי עד שמגיעים למקסימום שהוגדר (cloudsql_vector_iterative_filtering_max_neighbors). כל ההתאמות למסנן נספרות במסגרת LIMIT ומוסרות מסריקות נוספות של אינדקס הווקטורים.

הפעלת סינון איטרטיבי

כברירת מחדל, הסינון האיטרטיבי מושבת בכל הסשנים ובכל המכונות של Cloud SQL.

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

SET SESSION cloudsql_vector_iterative_filtering=on;

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

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

כוונון הסינון האיטרטיבי

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

כדי להגדיר את המשתנה הזה לסשן, משתמשים בהצהרת ה-SQL הבאה:

SET cloudsql_vector_iterative_filtering_max_neighbors=600;

ברירת המחדל היא 500, והמספר המינימלי הוא 10.

מגבלות

אלה המגבלות של שימוש בסינון איטרטיבי:

  • אין הבטחה: כשמשתמשים בסינון איטרטיבי, Cloud SQL מנסה למצוא את מספר התוצאות שצוין בסעיף LIMIT, אבל לא מבטיח שהמספר יימצא. זה יכול לקרות אם מגיעים למספר המקסימלי של השכנים (cloudsql_vector_iterative_filtering_max_neighbors) לפני שמתקיים התנאי של LIMIT, או אם אין מספיק שורות שתואמות למסנן בטבלה.

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

בדיקת סטטוס החלופה בחיפושי ANN

יש מקרים מסוימים שבהם חיפוש ANN חוזר לחיפוש KNN. למשל:

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

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

כדי לראות את סטטוס החלופה, משתמשים בפקודה הבאה בלקוח MySQL:

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

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

דוגמה: יצירת אינדקס וקטורי והרצת שאילתת ANN

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

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

    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. יוצרים את אינדקס הווקטורים באמצעות הפונקציה L2_squared כדי למדוד מרחק.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. כדי לבצע חיפוש ANN עם LIMIT של 4 תוצאות חיפוש, משתמשים בתחביר הבא:

    SELECT title
    FROM books
    ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
    LIMIT 4;
    
    SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist
    FROM books
    ORDER BY dist
    LIMIT 4;
    

חיפוש K-nearest neighbors ‏(KNN)

כדי לבצע חיפוש של K השכנים הקרובים ביותר, משתמשים בפונקציה vector_distance עם אפשרות למדידת מרחק ופונקציית המרה של וקטור (string_to_vector או vector_to_string) בהצהרת SELECT. משתמשים בתחביר הבא:

SELECT vector_distance(string_to_vector('[1,2,3]'),
                      string_to_vector('[1,2,3]'),
                      'Distance_Measure=dot_product');

מחליפים את הערכים [1,2,3] בערכי ההטמעה של הנתונים.

בדוגמה הבאה מוסבר איך להשתמש בשאילתה הזו עם הפונקציה cosine_distance ועם פונקציית ההמרה של הווקטור string_to_vector.

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

קבלת מרחק קוסינוס בשאילתת KNN

משתמשים בפונקציה cosine_distance של Cloud SQL כדי לחשב את המרחק באמצעות קוסינוס.

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

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

משתמשים בפונקציה dot_product של Cloud SQL כדי לחשב את המרחק באמצעות מכפלה סקלרית.

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

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

משתמשים בפונקציה l2_squared_distance של Cloud SQL כדי לחשב את המרחק באמצעות L2 בריבוע.

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

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