בדף הזה מפורטות הגרסאות השונות של אופטימיזציית השאילתות ב-Spanner, ומוצגת היסטוריה של הגרסאות האלה. גרסת ברירת המחדל הנוכחית היא 8. מידע נוסף על אופטימיזציית שאילתות זמין במאמר סקירה כללית על אופטימיזציית שאילתות.
מערכת Spanner מפיצה עדכונים של אופטימיזציית שאילתות כגרסאות חדשות של אופטימיזציית שאילתות. כברירת מחדל, כל מסד נתונים מתחיל להשתמש בגרסה העדכנית ביותר של האופטימיזציה לא לפני 30 יום אחרי שהגרסה הזו פורסמה.
אתם יכולים לנהל את הגרסה של אופטימיזציית השאילתות שבה השאילתות שלכם משתמשות במסדי נתונים של GoogleSQL-dialect ו-PostgreSQL-dialect. לפני שמאשרים את הגרסה האחרונה, אפשר להשוות בין פרופילי הביצועים של השאילתות בגרסאות קודמות לבין פרופילי הביצועים בגרסה האחרונה. מידע נוסף זמין במאמר בנושא ניהול האופטימיזציה של השאילתות.
היסטוריית הגרסאות של הכלי לאופטימיזציה של שאילתות
בהמשך מופיע סיכום של העדכונים שבוצעו לאופטימיזציה של השאילתות בכל מהדורה.
גרסה 9: 21 ביולי 2026 (הגרסה העדכנית)
שיפור היעילות של הצטרפויות מסוג distributed apply (DA) על ידי שליחת העמודות הנדרשות מהקלט לצד המיפוי של ההצטרפות.
המערכת בוחרת באופן אוטומטי את האינדקסים בעמודות מחושבות, כשאותו ביטוי מחושב הוא מסנן או תנאי הצטרפות בשאילתה.
לדוגמה, מאפשר בחירה של האינדקס ב-
Singers((LOWER(FirstName)))אם הוא קיים בשאילתה הבאה:GoogleSQL
SELECT s.SingerId, s.FirstName, s.LastName FROM Singers s WHERE LOWER(s.FirstName) > 'k' LIMIT 10;PostgreSQL
SELECT s.singerid, s.firstname, s.lastname FROM singers s WHERE LOWER(s.firstname) > 'k' LIMIT 10;שיפור הביצועים של חיפוש באינדקסים משולבים באמצעות אצווה ומיון של מפתחות לחיפושים רציפים יעילים באחסון.
שיפורים קלים בהערכת העוצמה (cardinality).
אם אין
LIMITמעל הפעולה apply, המערכת תעדיף באופן היוריסטי תוכניות עם distributed apply על פני apply עם distributed union בצד המפה.בוחר תוכניות של איחוד אינדקסים בצורה אגרסיבית יותר.
שיפור הביצועים של
GROUP BYבאמצעות הרחבת הצבירה מבוססת הסריקה כדי לתמוך בפרדיקטים של מסננים שבהם מפתח הצבירה מושווה לפונקציות שכוללות קבועים ופרמטרים.ההגדרה מאפשרת אופטימיזציה של תוכניות על סמך עלויות בשאילתות שכוללות טבלאות עם סכימות בעלות שם.
גרסה 8: 28 באוקטובר 2024 (ברירת מחדל)
סעיפי
WITHנלקחים בחשבון כשבוחרים תוכנית שמבוססת על עלות.שיפור הביצועים של שאילתות מבוזרות מסוג cross apply ושאילתות חיפוש באינדקס.
שיפור
JOINשינוי הסדר.שיפור הביצועים של שאילתות עם תנאי
IN (...)גדולים.שיפרנו את הביצועים של
GROUP BYבמקרים מסוימים.שיפורים נוספים, כולל טיפול יעיל יותר בשאילתות עם
LIMIT, מפתחות זרים ובחירת אינדקס.
גרסה 7: 22 במאי 2024
הוספנו תמיכה בבחירה מבוססת-עלות של תוכניות איחוד אינדקסים.
נוסף תמיכה בבחירה חכמה של תוכניות חיפוש לעומת תוכניות סריקה על סמך נתונים סטטיסטיים של שאילתות שאין להן פרדיקטים שניתן לחפש בהם את כל החלקים העיקריים.
הוספנו תמיכה בבחירה של הצטרפויות גיבוב (hash joins) על סמך עלות.
גרסה 6: 11 בספטמבר 2023
שיפור של העברת מגבלות והעברת פרדיקטים באמצעות הצטרפות חיצונית מלאה.
שיפור ההערכה של עוצמת הקבוצה ומודל העלויות.
הופעלה אופטימיזציה מבוססת-עלות לשאילתות DML.
גרסה 5: 15 ביולי 2022
שיפור מודל העלויות לבחירת אינדקס, לניהול הפצה, למיקום מיון ולבחירת
GROUP BY.הוספנו תמיכה בבחירת אלגוריתם לחיבור על סמך עלות, שבוחר בין חיבור מסוג hash לבין חיבור מסוג apply. עדיין צריך להשתמש ברמז לשאילתה כדי לבצע מיזוג של הצטרפות.
הוספנו תמיכה בחוק החילוף של הצטרפות על בסיס עלות.
גרסה 4: 1 במרץ 2022
שיפורים בבחירה של אינדקס משני.
- שיפור השימוש באינדקס משני במסגרת שאילתת איחוד (join) בין טבלאות משולבות.
- שיפור הכיסוי של השימוש באינדקס משני.
- שיפרנו את בחירת האינדקסים כשנתוני האופטימיזציה לא עדכניים.
- עדיף להשתמש באינדקסים משניים עם פרדיקטים בעמודות מובילות באינדקס, גם אם הנתונים הסטטיסטיים של האופטימיזציה לא זמינים או מדווחים שמסד הנתונים הטבלאי קטן.
הוספנו הצטרפות גיבוב חד-מעברית, שמופעלת על ידי הרמז החדש
hash_join_execution.רמז להצטרפות:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=hash_join, hash_join_execution=one_pass} (...)PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=hash_join, hash_join_execution=one_pass */ (...)המצב החדש מועיל כשהקלט של הצד לבנייה של ה-hash join גדול. צפויים ביצועים טובים יותר של הצטרפות גיבוב במעבר אחד אם רואים את הדברים הבאים בפרופיל של ביצוע השאילתה:
- מספר ההרצות בצד ימין של הצומת הצאצא של הגיבוב גדול יותר ממספר ההרצות באופרטור הגיבוב.
- גם זמן האחזור של צאצא ימני של אופרטור ה-hash join גבוה.
כברירת מחדל (
hash_join_execution=multi_pass), אם קלט הצד של ה-build של ה-hash join גדול מדי ולא נכנס לזיכרון, הצד של ה-build מתפצל לכמה קבוצות, ויכול להיות שנסרוק את הצד של ה-probe כמה פעמים. במצב החדש (hash_join_execution=one_pass), אם קלט הצד של ה-build לא נכנס לזיכרון, ה-hash join יועבר לדיסק, ותמיד יסרוק את הצד של ה-probe רק פעם אחת.שיפור בבחירת מספר המקשים שמשמשים להזזה.
גרסה 3: 1 באוגוסט 2021
נוסף אלגוריתם חדש לצירוף, merge join, שמופעל באמצעות ערך חדש של רמז לשאילתה JOIN METHOD.
רמז להצהרה:
GoogleSQL
@{join_method=merge_join} SELECT ...PostgreSQL
/*@ join_method=merge_join */ SELECT ...רמז להצטרפות:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=merge_join} (...)PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=merge_join */ (...)נוסף אלגוריתם חדש לצירוף, push broadcast hash join, שמופעל באמצעות ערך חדש של רמז לשאילתה JOIN METHOD.
רמז להצטרפות:
GoogleSQL
SELECT ... FROM (...) JOIN@{join_method=push_broadcast_hash_join} (...)PostgreSQL
SELECT ... FROM (...) JOIN/*@ join_method=push_broadcast_hash_join} */ (...)הוספנו את האופרטור distributed merge union, שמופעל כברירת מחדל כשזה רלוונטי. הפעולה הזו משפרת את הביצועים של השאילתות.
שיפור קל בביצועים של סריקה ב-
GROUP BYכשאין צבירה MAX או MIN (או HAVING MAX/MAX) ברשימת SELECT. לפני השינוי הזה, Spanner טען את העמודה הנוספת שלא מקובצת גם אם היא לא נדרשה על ידי השאילתה.לדוגמה, נניח את הטבלה הבאה:
GoogleSQL
CREATE TABLE myTable( a INT64, b INT64, c INT64, d INT64) PRIMARY KEY (a, b, c);PostgreSQL
CREATE TABLE myTable( a bigint, b bigint, c bigint, d bigint, PRIMARY KEY(a, b, c) );לפני השינוי הזה, השאילתה הבאה הייתה טוענת את העמודה
cגם אם היא לא נדרשת על ידי השאילתה.SELECT a, b FROM myTable GROUP BY a, bשיפור הביצועים של חלק מהשאילתות עם
LIMITכשיש אופרטור cross apply שהוצג על ידי joins והשאילתה מבקשת תוצאות ממוינות עם LIMIT. בעקבות השינוי הזה, האופטימיזציה מחילה את המיון עם ההגבלה בצד הקלט של cross apply קודם.דוגמה:
GoogleSQL
SELECT a2.* FROM Albums@{FORCE_INDEX=_BASE_TABLE} a1 JOIN Albums@{FORCE_INDEX=_BASE_TABLE} a2 USING(SingerId) ORDER BY a1.AlbumId LIMIT 2;PostgreSQL
SELECT a2.* FROM albums/*@ force_index=_base_table */ a1 JOIN albums/*@ force_index=_base_table */ a2 USING(singerid) ORDER BY a1.albumid LIMIT 2;השיפור בביצועי השאילתות מתבצע על ידי העברת יותר חישובים דרך
JOIN.הפעולה מעבירה יותר חישובים, שעשויים לכלול שאילתת משנה או בניית מבנה, דרך הצטרפות. השיפור הזה משפר את ביצועי השאילתות בכמה דרכים, למשל: אפשר לבצע יותר חישובים באופן מבוזר, ואפשר גם להעביר למטה יותר פעולות שתלויות בחישובים שהועברו. לדוגמה, אם לשאילתה יש מגבלה וסדר המיון תלוי בחישובים האלה, אפשר להעביר את המגבלה גם דרך הצטרפות.
דוגמה:
SELECT t.ConcertDate, ( SELECT COUNT(*) FROM UNNEST(t.TicketPrices) p WHERE p > 10 ) AS expensive_tickets, u.VenueName FROM Concerts t JOIN Venues u ON t.VenueId = u.VenueId ORDER BY expensive_tickets LIMIT 2;
גרסה 2: 1 במרץ 2020
- הוספת אופטימיזציות לבחירת אינדקס.
- שיפור הביצועים של פרדיקטים מסוג
REGEXP_CONTAINSו-LIKEבנסיבות מסוימות. - משפר את הביצועים של סריקה ב
GROUP BYבמצבים מסוימים.
גרסה 1: 18 ביוני 2019
כולל הרבה אופטימיזציות מבוססות-כללים, כמו predicate pushdown, limit pushdown, redundant join ו-redundant expression removal.
משתמש בנתונים סטטיסטיים על נתוני משתמשים כדי לבחור באיזה אינדקס להשתמש כדי לגשת לכל טבלה.
המאמרים הבאים
- מידע נוסף על אופטימיזציית שאילתות זמין במאמר מידע על אופטימיזציית שאילתות.
- כדי לנהל את גרסת האופטימיזציה ואת חבילת הנתונים הסטטיסטיים של התרחיש, אפשר לעיין במאמר ניהול אופטימיזציית השאילתות.