סינון דינמי ב-AlloyDB AI משפר את החיפושים הווקטוריים המסוננים על ידי בחירה דינמית של אסטרטגיית הסינון היעילה ביותר במהלך הרצת השאילתה. כדי לתכנן שאילתות וקטוריות עם ביצועים גבוהים בלי לכוונן את האינדקס באופן ידני, חשוב להבין איך הכלי לאופטימיזציה של שאילתות עובר בין סינון מוטבע לסינון מקדים.
מהו סינון אדפטיבי?
סינון דינמי מנתח את מבני השאילתות ואת התפלגויות הנתונים במהלך הרצת השאילתה, כדי לבחור באופן דינמי את אסטרטגיית הסינון היעילה ביותר, כמו סינון מוטבע או סינון מקדים.
הכלי לאופטימיזציה של שאילתות ב-AlloyDB AI משתמש בניתוח מבוסס-עלות כדי לקבוע אם סינון מוטבע או סינון מקדים מספק את הביצועים הטובים ביותר בכל שלב נתון במהלך הרצת השאילתה.
הסוג הזה של אופטימיזציה תומך בחיפושי וקטורים מסוננים של AlloyDB AI, שבהם סינון אדפטיבי עובר אוטומטית בין שימוש בווקטור לבין שימוש באינדקס מטא-נתונים, וכך מניב תוצאות יעילות ומדויקות ללא התערבות ידנית.
מעבר דינמי בין שיטות סינון
סינון אדפטיבי מחליף באופן אוטומטי ודינמי בין סינון מוטבע לבין אסטרטגיות של סינון מקדים במהלך הרצת שאילתה, על סמך מבני שאילתות וחלוקות נתונים בזמן אמת. הכלי לאופטימיזציה של שאילתות ב-AlloyDB AI משתמש בניתוח מבוסס-עלות כדי לקבוע איזו אסטרטגיה מספקת את הביצועים הטובים ביותר בכל שלב.
מסינון בתוך השורה לסינון מקדים
כשהכלי לאופטימיזציה קובע שסינון מראש יעיל יותר, הסינון האדפטיבי מפעיל מעבר מסינון מוטבע לסינון מראש במהלך ההפעלה. התוכנית לביצוע השאילתה משתנה באופן דינמי בהתאם.
לדוגמה, התוכנית יכולה להציג Bitmap assisted pre-filtering בשדה Execution Strategy (אסטרטגיית ביצוע) אם האופטימיזציה קובעת שסינון מקדים יעיל יותר בשלב הזה של השאילתה. השינוי הדינמי הזה מתרחש כשהמערכת מסתגלת לנתונים בפועל שהיא נתקלת בהם במהלך הרצת השאילתה.
Limit (actual rows=10 loops=1)
-> Custom Scan (vector scan) on t1 (actual rows=10 loops=1)
Execution Strategy: Bitmap assisted pre-filtering
Order By: (vec_col <=> '[...]'::vector)
Limit: 10
-> Bitmap Index Scan on btree_idx (actual rows=10000 loops=1)
Index Cond: (int_col <= 100000000)
כשמשתמשים ב-Execution Strategy: Bitmap assisted pre-filtering, Bitmap Index Scan נפרד מסנן קודם קבוצת נתונים גדולה. אם הסינון המקדים הזה מצמצם את רשימת המועמדים, המערכת לא משתמשת באינדקס הווקטורי לחיפוש הסופי של הדמיון הווקטורי.
מסינון מקדים לסינון בתוך השורה
סינון דינמי יכול גם לעבור באופן דינמי מסינון מקדים לסינון מוטבע, אם הכלי לאופטימיזציה של שאילתות ב-AlloyDB AI קובע שסינון מוטבע יעיל יותר למאפייני השאילתה הנוכחית.
במקרים כאלה, תוכנית לביצוע שאילתה מותאמת באופן דינמי כדי לשקף עיבוד ישיר יותר של נתוני הווקטור ללא שלב סינון מקדים מפורש לפני סריקת הווקטור. הגמישות הזו עוזרת להשיג ביצועים אופטימליים כשהתפלגויות הנתונים או פרמטרים של שאילתות משתנים במהלך זמן הריצה.
לדוגמה, תוכנית לביצוע שאילתה מציגה vector scan בשדה Execution Strategy (אסטרטגיית ביצוע) כשהכלי לאופטימיזציה קובע שאסטרטגיית סינון מוטבעת יעילה יותר עבור השאילתה הנתונה.
Limit (actual rows=10 loops=1)
-> Custom Scan (vector scan) on t1 (actual rows=10 loops=1)
Execution Strategy: Bitmap assisted vector Scan on scann_idx
Order By: (vec_col <=> '[...]'::vector)
Limit: 10
Num Requalifications: 0
Num filtered: 1000
-> Bitmap Index Scan on btree_idx (actual rows=10000 loops=1)
Index Cond: (int_col <= 100000000)
בדוגמה הזו, הערך של Execution Strategy הוא Bitmap assisted vector Scan on scann_idx, עם Bitmap Index Scan בסיסי של btree_idx. המשמעות היא שהחיפוש הווקטורי משתמש במסנן מפת סיביות, שנוצר על ידי סריקת אינדקס מפת הסיביות על סמך התנאי int_col <= 100000000. לאחר מכן, Custom Scan (vector scan) מעבד רק את השורות שמזוהות על ידי מפת הביטים הזו, ומשלב את הסינון ישירות בתהליך הסריקה של הווקטור.
דוגמה: איך סלקטיביות מפעילה מעבר דינמי
סינון דינמי מתבסס על הסלקטיביות של המסננים הרגילים. אם מסנן מסיר כמות גדולה של נתונים, סביר להניח שהאופטימיזציה תבחר בסינון מקדים. אם המסנן משאיר את רוב הנתונים ללא שינוי, סביר להניח שהאופטימיזציה תבחר בסינון מוטבע.
כדי לראות את המעבר הדינמי הזה בזמן אמת, מריצים את אותה שאילתה ומשנים את הסלקטיביות של פסוקית WHERE.
לדוגמה, כששולחים שאילתה לטבלה גדולה של מוצרים קמעונאיים, יכול להיות שתרצו לבצע חיפוש וקטורי רק על פריטים מתחת למחיר מסוים.
סלקטיביות נמוכה
קודם כל, מחפשים מוצרים במחיר של עד 1,000$. כמעט כל המוצרים במסד הנתונים עולים פחות מ-1,000$, ולכן הסלקטיביות של המסנן נמוכה. הכלי לאופטימיזציה של שאילתות ב-AlloyDB AI קובע שלא יעיל לאסוף כמעט את כל מסד הנתונים לרשימה שעברה סינון מקדים, ולכן הוא מבצע סריקה וקטורית מוטבעת.
אם תסתכלו על תוכנית השאילתה, תראו שהמערכת התאימה את עצמה באופן דינמי למערך הנתונים העצום ובחרה בסינון מוטבע.
Limit (actual rows=10)
-> Custom Scan (vector scan)
Execution Strategy: Bitmap assisted vector Scan on scann_idx
Order By: (vec <=> '[...]'::vector)
-> Bitmap Index Scan
Index Cond: (price <= 1000)
סלקטיביות גבוהה
לאחר מכן, משנים את השאילתה כדי לחפש מוצרים במחיר של פחות מ-10$. כשהשאילתה מתחילה לפעול, הכלי לאופטימיזציה של שאילתות ב-AlloyDB AI מתכונן להשתמש בסינון מוטבע. המתכנן מניח באופן שגוי שהמסנן לא מאוד סלקטיבי. זה קורה יותר ממה שמצפים כי הנתונים הסטטיסטיים שמשמשים ליצירת ההערכות האלה לא תמיד מדויקים או עדכניים. עם זאת, המערכת קובעת במהירות שהמסנן מחזיר רק פריטים ספורים מתוך מסד הנתונים: מעט מאוד פריטים במסד הנתונים נמכרים במחיר כזה נמוך. הכלי לאופטימיזציה קובע שאיסוף השורות האלה לפני ביצוע סריקת הווקטורים הוא מהיר הרבה יותר, ולכן הוא משנה את האסטרטגיה באופן דינמי לסינון מראש.
התוכנית לביצוע השאילתה משקפת את השינוי הזה בזמן אמת. המערכת בחרה לסנן מראש את מערך הנתונים הקטן לפני סריקת הווקטורים.
הבחירה הראשונית של הכלי לתכנון
Limit (actual rows=10)
-> Custom Scan (vector scan)
Execution Strategy: Bitmap assisted vector Scan on scann_idx
Order By: (vec <=> '[...]'::vector)
-> Bitmap Index Scan
Index Cond: (price <= 10)
הפעלה בפועל (מתג אדפטיבי)
Limit (actual rows=10)
-> Custom Scan (vector scan)
Execution Strategy: Bitmap assisted pre-filtering
Order By: (vec <=> '[...]'::vector)
-> Bitmap Index Scan
Index Cond: (price <= 10)
לא צריך לשכתב את קוד האפליקציה או לעדכן באופן ידני את האינדקסים של מסד הנתונים כשהתפלגות הנתונים משתנה עם הזמן. AlloyDB AI מטפל בלוגיקת הניתוב בכל שאילתה, כדי להבטיח ביצועים גבוהים.