הצגת Insert לטבלה מאונדקסת ב-Execution Plan

יום חמישי, אוגוסט 13, 2015

בדרך כלל אנחנו משתמשים ב-Execution Plan כדי לבחון ולשפר פעולות Select, אולי מפני ש-Isert הוא מובן מאליו ואין מה לשפר בו (למעט ה-Select שאותו מכניסים לטבלה), ואולי מפני שבמערכות OLTP ה-Insert-ים הם קטנים ולא מעניינים, בניגוד לפעולות ה-Select שיכולות להיות עתירות משאבים.כך או כך, ניצור טבלה עם מבחר אינדקסים (כולם מיותרים ונועדו לצורך התרגול) ונבדוק כיצד נראית פעולת ה-Insert.הטבלה, כמקובל במקומנו, לפי מבנה טבלת הודעות השגיאה sys.messages: Create Table #T(message_id Int, language_id Int, severity SmallInt, ...
תגיות: , ,
תגובה אחת

שיפור ביצועי Join עצמי

יום שישי, אוגוסט 22, 2014

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

אופטימיזציה של שליפות עם תנאים על תחומים

יום ראשון, אוגוסט 3, 2014

אב”ג פרסם לאחרונה שני פוסטים העוסקים בנושא זה: Optimization Tips for Multiple Range Predicates, Part 1Optimization Tips for Multiple Range Predicates, Part 2 הפוסט הזה נכתב בהשראתו, ויש לתת קרדיט למאסטר!עסקינן בשליפה מטבלאות ששורותיה כוללות נקודות התחלה וסיום (או מ.. עד..). באופן טבעי זה מתייחס לתאריכים (דוגמה טובה לכך הן טבלאות Slowly Changing Dimensions במחסני נתונים), אך לא רקבבעיות מהסוג של למצוא את כל האירועים שהתרחשו – במלואם או בחלקם – בין שני תאריכים, יש נטייה להסתבך: הרי יכול להיות שהאירוע התחיל לפני והסתיים תוך כדי או התחיל לפני והסתיים אחרי וכך הלאה, מתרגמים את הכל למערכת סבוכה של...
אין תגובות

דוגמה ליצירת אינדקס לטבלה

יום חמישי, אפריל 17, 2014

לכאורה לא מסובך ליצור אינדקס לטבלה: נניח שהתבקשנו ליצור אינדקס בטבלה MyTbl על עמודה MyCol, אזי אנחנו מריצים את הפקודה הבאה- Create Index Idx_MyTbl_MyCol On MyTbl(MyCol); והנה יש לנו אינדקס כאשר אהבנו.. לא כך? לא כך! כאשר הייתי בתחילת דרכי ושמעתי שאינדקסים משפרים ביצועים באופן דרסטי (מה שנכון), חשבתי לתומי שכל מה שעלי לעשות זה ליצור אינדקס על כל עמודה בטבלה (כי הרי אין לדעת לפי מה המשתמשים ירצו לפלטר ולמיין אותה), וכבר ראיתי את עצמי בעיני רוחי כמו איזה אב"ג שמבין עניין, מתקתק בנון-שלאנטיות פקודות שאיש אינו מבין, אה-ווּאלָה!כמובן שמהר מאוד הבנתי שזה לא הולך כך ושאינדקסים כאלו יצרו...
תגיות: , ,
אין תגובות

חפיפה בין אינדקסים

יום ראשון, פברואר 16, 2014

נתקלתי פעם במקרה הבא- טבלה שהוגדרו לה שני אינדקסים: Primary Key & Clusterd Index על עמודות Col1, Col2, Col3. Unique Index על עמודות Col1, Col2. כבר במבט ראשון אפשר לראות בעייה בסיסית – אם כל צירוף של Col1, Col2 הוא יחודי, מדוע המפתח כולל גם את עמודה Col3?זה לא נכון, מי שינסה להכניס לטבלה את הצירופים 1,1,2ו-1,1,3 יקבל הודעת שגיאה בגלל האינדקס השני (למרות שלפי הגדרת המפתח שני הצירופים נראים תקינים), ומי שיצור Foreign Key לטבלה – יאלץ לכלול בה עמודה מיותרת ללא צורך. יתכן ש"כוונת המשורר" הייתה שהמפתח הוא Col1,Col2 אבל הוא רצה ליצור Clustered Index שיכלול...
אין תגובות

סדר העמודות באינדקס

יום רביעי, ינואר 15, 2014

ניצור שני העתקים של טבלת המערכת sys.messages. המפתח של הטבלה הוא 2 העמודות (message_id,language_id), וכך בכל העתק ניצור את המפתח בסדר אחר של העמודות, ונראה האם ומתי זה משנה, ומה עדיף ומתי.הפואנטה כאן היא העובדה שהגרנולריות או הסלקטיביות של language_id היא קטנה (יש מעט ערכים שונים בעמודה זו, 11 בגרסה R2(,ואילו זו של message_id היא גדולה (כ-9000 בגרסה הנ"ל): Use tempdb;Go If Object_ID('T_Messages1','U') Is Not Null Drop Table T_Messages1;Select * Into T_Messages1 From sys.messages;Go Alter Table T_Messages1Add Constraint Primary Key Clustered(message_id,language_id);Go If Object_ID('T_Messages2','U') Is Not Null Drop Table T_Messages2;Select * Into T_Messages2 From sys.messages;Go Alter Table T_Messages2Add Constraint Primary Key...
תגיות: , ,
אין תגובות

שימוש באינדקסים בעת ביצוע Count

יום חמישי, דצמבר 5, 2013

איזה מידע מכיל NonClustered Index? נושא די בסיסי והתשובה די ברורה: אינדקס "רגיל" מכיל את נתוני העמודה או העמודות עליהן הוא נוצר, קישור למיקום הפיזי של כל שורה בו לשורה המתאימה בטבלה עצמה, ואם החכמנו והתחכמנו ויצרנו Covered Index – הוא כולל גם אותן עמודות הכלולות בו, אם כי ללא הפונקציונליות של חיפוש / אגרגציה / מיון וכו' שהאינדקס מאפשר לנו.כך גם אני חשבתי וזה די נכון, עד שהתברר לי להפתעתי שזה לא לגמרי כך. במה דברים אמורים?נתחיל מהברור מאליו- ניצור טבלה מטבלת המערכת sys.messages, וניצור אינדקס רגיל על אחת העמודות (message_id): Use tempdb;Go If Object_ID('T_Messages','U') Is Not Null...
אין תגובות

שימוש באינדקסים באי שיוויונים

יום חמישי, נובמבר 28, 2013

ניצור שתי טבלאות לצורך בדיקה כיצד המערכת מנצל אותם כשיש אי שיוויונים ב-Where: If Object_ID('T1','U') Is Not Null Drop Table T1;Select *Into T1From sys.messages; Alter Table T1 Add Constraint PK_T1 Primary Key Clustered (message_id,language_id);Go If Object_ID('T2','U') Is Not Null Drop Table T2;Select *Into T2From sys.messages; Alter Table T2 Add Constraint PK_T2 Primary Key Clustered (language_id,message_id);Go כדאי לשים לב שיש בכל טבלה הרבה message_id ומעט Language_id, ולכן יצרתי שתי טבלאות – בראשונה message_id ראשון ובשניה language_id ראשון.נתחיל מהמקרה הפשוט –...
תגיות: , ,
אין תגובות