סטטיסטיקה: עדכון וקבלת החלטות

יום רביעי, אפריל 13, 2016

הפוסט שלהלן ממחיש את השימוש בסטטיסטיקה על ידי המערכת לבחירת ה-Execution Plan, ואת השפעתה של סטטיסטיקה לא מעודכנת על שימוש זה ואיכות הבחירה. בעזרת טבלת sys.messages (טבלת מערכת בת כ-250,000 שורות) אבנה טבלה עם נתונים היסטוריים, כלומר- אכניס את תוכן טבלת המערכת לטבלה שאבנה, בתוספת תאריך: If Object_ID('T_Messages','U') Is Not Null Drop Table T_Messages; Create Table T_Messages ( DateTime Not Null, message_id Int Not Null, language_id Int Not Null, ...

אפטימיזציה לבעיית Top

יום שישי, יולי 25, 2014

נתונה לנו בעייה פחות או יותר כזו: יש למצוא את 30 המכירות הראשונות היום של פריטים X,Y,Z;או אולי את 10 הקפיצות לרוחק הטובות ביותר של הספורטאיות A,B,C,D,E וכו’.לא מדובר ב-30 המכירות הראשונות של כל אחד מהפריטים (90 בסה”כ), וגם לא ב-10 המכירות הראשונות של כל אחד (שיסתכמו בסופו של דבר ל-30); אלא ב-30 של כולם ביחד ללא כל התחייבות לחלוקה הפנימית. ניצןר לשם כך טבלה להדגמה המתבססת על טבלת sys.messages, נוסיף לה טבלת עזר עם רשימת language_id וננסה לשלוף את 10 ה-message_id הראשונים שלהם. נתחיל מהטבלאות: Select *Into #T_MessagesFrom ...
אין תגובות

יעילות תנאי In

יום שישי, דצמבר 28, 2012

האופרטור In (כחלק מפסוקית ה-Where) הוא מאוד פופלרי כשרוצים להשוות בין ערך לרשימת ערכים ללא שימוש ב-Or מסובך. למשל- במקום Where @X=1 Or @X=2 Or @X=3 אפשר בקיצור (Where @X In (1,2,3. יתרוהו הגדול של האופרטור In שהוא פשוט להבנה ונוח לשימוש, ולא פעם משמיצים את ביצועיו שלא בצדק. כל עוד מדובר ברשימה קצרה של מספר ערכים – אין טעם להתעמק בביצועים, אך מה קורה אם מדובר ברשימה ארוכה? אני אבדוק שלוש אפשרויות: 1. In עם רשימת ערכים מפורשת. 2. In הפונה לטבלה (ממופתחת ומאונדקסת...
אין תגובות

שימוש באינדקס לחיפוש לפי עמודה משנית

יום רביעי, נובמבר 7, 2012

כאשר יוצרים אינדקס על טבלה לפי עמודה1, עמודה2, עמודה3; הדעת נותנת שהוא יהיה שימושי כשנבצע חיפוש או מיון לפי עמודה1, עמודה2, עמודה3.. מה יקרה אם נחפש לפי עמודה2 דווקא? למשל- יש לנו טבלת מכירות בה העמודה הראשית באינדקס היא התאריך, והעמודה המשנית המוכר; ואנחנו מעוניינים לבצע חיפוש לפי מוכר.. השכל הישר (שלי לפחות) אומר שזה תלוי בסלקטיוויות של העמודה הראשית: אם הסלקטיוויות נמוכה אז כדאי ואם היא גבוהה – לא. כלומר- אם בטבלת המכירות הנ"ל יש רק שני תאריכים שונים (על פני הרבה מאוד שורות) ואנחנו מחפשים את המוכר X, המערכת תבצע Seek...
אין תגובות

לעזור לסבתא לחצות את הכביש

יום שלישי, פברואר 7, 2012

נסיונות לעזור לאופטימייזר של ה-SQL Server משול לעיתים לניסיון המיתולוגי לעזור לזקנה לחצות את הכביש: גרמנו יותר תועלת מנזק.. נכון שלא תמיד זה כך, ולכן יש להפעיל שיקול דעת. הפעם דוגמה מתי לא כדאי: נתונות שתי טבלאות- אחת גדולה (100,000 שורות) ואחת קטנה (33 שורות) ואנחנו מעוניינים לבצע Join בינהן. העמודה בטבלה הקטנה איתה מתבצע ה-Join היא יחודית ולכאורה היא Primary Key, אך לטבלאות לא הוגדרו אינדקסים. אנחנו רוצים לעזור לאופטימייזר: הוא הרי יבצע Scan לטבלה הגדולה, ולכל שורה יחפש התאמה בטבלה הקטנה; ומכיוון שהוא אינו "יודע" שיכולה להיות רק התאמה...
אין תגובות

Parallelism

יום שישי, ינואר 27, 2012

כאשר לשרת יש יותר ממעבד אחד הוא יכול לבחור לבצע פעולות במקביל וזה משפיע על בחירת ה-Execution Plan האופטימלי. בפוסט הקודם הראיתי כיצד במקרה של Join בין טבלה לא מאונדקסת לטבלה עם Primary Key & Clustered Index המערכת תבחר בעיבוד במקביל: Select * From messages T1 Inner Join messages_ClstInd T2 On T1.message_id=T2.message_id And T1.language_id=T2.language_id; מאוד יכול להיות שחלק שמי שניסה את הקוד...
אין תגובות

השפעת האינדקסים על ביצוע Join בין טבלאות

יום חמישי, ינואר 26, 2012

כיצד המערכת מבצעת Join ומה השפעת האינדקסים ומספר הרשומות על כך? בהמשך לפוסט הקודם- אנתח מספר דוגמאות מבחינת התוכנית שהמערכת תבחר ולא מבחינת הביצועים, והן יתבססו על הטבלאות והאינדקסים שיצרנו בפעם הקודמת: --1. No Indexes Select * Into messages From sys.messages; Go   --2. Clustered Primary Key on message_id,language_id Select * Into messages_ClstInd From ...

השפעת האינדקסים על חיפוש פשוט בטבלה

יום שלישי, ינואר 24, 2012

כיצד המערכת מחפשת ערכים בטבלה ומה השפעת האינדקסים על כך? מדובר בנושא די בסיסי בתחום, והפוסט הזה מוקדש למי שעדיין אינו מכיר. טבלת המערכת הגדולה ביותר היא sys.messages הכוללת את הודעות השגיאה של המערכת (קרוב ל-100,000 שורות בגרסת 2008 ועוד היד נטוייה בגרסאות הבאות): Select * From sys.messages; ניצור מספר עותקים ממנה ונאנדקס כל אחד בדרך אחרת, ונבדוק כיצד מתבצע החיפוש בכל פעם. נתחיל עם עותק ללא אינדקסים כלל: --1. No Indexes ...
אין תגובות

ריבוי תנאים הפונים לאותו אובייקט

יום ראשון, ינואר 22, 2012

נניח שאנחנו מחפשים עובד שיש לו גם הכשרה ב-SQL Server, גם ב-C# וגם ב-XML, או לחילופין סכימה בדטבייס שברשימת האובייקטים שלה יש גם פרוצדורות, גם טבלאות, וגם Views. כמקובל צריך לנסח שליפה ותנאים, אך יש לשים לב שבשתי הדוגמאות הנ"ל כל התנאים פונים לאותה טבלה (טבלת ההכשרות או טבלת האובייקטים) ובדיקה של כל תנאי בנפרד תגרום לשלוש פניות לטבלה וזה קצת מיותר. נציע מספר פתרונות, ונבחן אותם באמצעות ה-Execution Plan וסיכומי Statistics IO לגבי פעולות הקריאה: לי עצמי לקח זמן רב להבין כיצד להיעזר באמצעים האלו, וגם כיום...
אין תגובות

ביצוע Lag (או Lead) תוך פניה אחת לטבלה

יום ראשון, יולי 17, 2011

פונקציות Lag ו-Lead עדיין אינן קיימות ב-SQL Server, אם כי ב-Oracle הן כבר אזרחיות ותיקות: הן מאפשרות לפנות מתוך רשומה לזו שלפניה (Lag) או לזו שאחריה (Lead), פעולה שהיא חיונית בשליפות המתארות סדרות נתונים לאורך זמן (שערי חליפין, סיכומים תקופתיים..) בהן אנו נדרשים להציג את השינוי באחוזים לעומת התקופה הקודמת. פעולה די טריוויאלית בסביבה עסקית, אולם בכלים הקיימים כיום ב-TSQL - יש לבצע שליפות מסובכות יחסית ולא כל כך יעילות הכוללות מספר פניות לטבלה (למשל- Join של הטבלה עם עצמה כך שלכל רשומה מהטבלה האחת מותאמת הרשומה הקודמת מהטבלה השנייה). עסקתי בנושא הזה מספר פעמים בעבר: ...
אין תגובות