Entity Framework והטעויות שיגרמו לכם לבעיות ביצועים

בעשור האחרון, מרבית הפיתוח מול הדטאבייסים עושה שימוש ב- ORM-ים כאלה ואחרים. אחד ה- ORM-ים הפופולריים בעולם הדוטנט, הוא Entity Framework. בפוסט הזה, אסקור טעויות נפוצות שמשליכות על ביצועים של עבודה מול ה- DB בעבודה עם ORM-ים באופן כללי, ובפרט בעבודה עם Entity Framework.
כלל הדוגמאות בפוסט מבוססות על ה- DB של Stack Overflow, בגרסה שהתאמתי עבור הקורס SQL שהקלטתי בעבר. הדוגמאות מבוססות על Entity Framework 6.2, על אף שחלקן רלוונטיות לכל סוגי ה- ORM-ים.

טעות #1 : בעיית ה- N+1

בואו נניח שאנחנו רוצים להציג את כל השאלות ב- Stack Overflow, ולצד כל שאלה – מי המשתמש שכתב אותה. נסתכל בקוד הבא:

using (var data = new Entities())

{

    foreach (var question in data.Posts.Where(k=>k.Title != null))

    {

        Console.WriteLine($"{question.Title} was asked by {question.User.DisplayName}");

    }

}

ועכשיו נשאלת השאלה – כמה שליפות SQL רצו פה מול ה- DB?להמשך קריאה

DbFunctions.TruncateTime ובעיית הביצועים המוחבאת

 

לאחרונה נתקלתי בבעיית ביצועים בעת עבודה עם Entity Framework שנגרמה כתוצאה משימוש במתודה DbFunctions.TruncateTime.image_thumb7

לטובת הדוגמא, בואו נסתכל על טבלה בשם Posts במבנה כמו בתמונה מצד שמאל.
הטבלה מכילהה מס’ עמודות, ובין היתר עמודת CreationDate מסוג datetime (או datetime2, פחות רלוונטי למקרה שלנו) שכוללת התאריך והזמן של יצירת רשומה.
נניח גם שהעמודה הזאת היא ה- clustered index של הטבלה (מדובר ב- clustered index הגיוני).

המטרה שלנו –  להביא את כל השורות שנוצרו בתאריך מסויים. למשל, נרצה להביא את כל השורות שנוצרו ב- 25.06.2016 (בלי חשיבות לזמן שבה הן נוצרו).
יש כמה דרכים אפשריות לעשות את זה. אפשר לעשות שאילתה על הטווח (בין ה-25 ל-26), או שיטה אחרת, אפשרית גם כן (למרות שגם יקרה קצת יותר בביצועים),  היא לעשות CAST לעמודה ל- date (ואז מאבדים למעשה את החלק של הזמן) ולהשוות לתאריך.… להמשך קריאה