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

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

חיפוש של שכנים קרובים משוערים (ANN)

כדי לבצע חיפוש ANN, משתמשים בפונקציה approx_distance במשפט SELECT ו-ORDER BY. צריך להשתמש בסעיף LIMIT בחיפוש ANN. אפשר גם לקבל את ערך המרחק על ידי הוספת 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 כדי להשיג את האיזון הטוב ביותר בין איכות החיפוש לביצועים עבור עומס העבודה הספציפי שלכם. אם מגדילים את הערך, הביצועים מושפעים אבל יכולת השליפה משתפרת.

בדוגמה הבאה מוצג איך להשתמש ב-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, יוחזרו 0 שורות.

אם אתם צופים שהמסנן בתנאי 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

בדוגמה הבאה מוסבר איך ליצור אינדקס וקטורי ולהריץ שאילתת 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;
    

חיפוש של השכנים הקרובים ביותר (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

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

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

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

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

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

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