Database Query Performance Case Studies: Large Volumes of Data
Michael Curry
By
July 3, 2023

In an earlier blog, we discussed how WebCE uses SQL Server's Query Store feature to identify and troubleshoot query performance.
Now let's dig a little deeper into one of the queries we improved.
The Query and Code
The query we’ll be troubleshooting in this article was our top resource consumer by total execution time per hour in peak traffic and accounted for around half of our total DB execution time:
SELECT * FROM CourseSection WHERE CourseId = @CourseId;
This query was generated from a basic ORM method call used in many places throughout our code. We often see queries generated by ORMs when troubleshooting as, while they are a consistent and straightforward way to get the data you need from code you’re working on, they can be overly generic, and it is easy to overlook the performance implications of how the methods are being called. Eventually we narrowed the likely problem down to a specific instance of the method call on one of our most heavily used LMS pages.
This page has a method that queries data about a course and the user’s progress and computes various flags used by the LMS system. The snippets below show the parts of this logic that are pertinent to this query call, and how it is used to compute a flag called isChapterMustRead:
public static void ComputeComplianceFlags(Course course)
{
…
// GetCourseSections executes the Query in shown above
var courseSections = GetCourseSections(courseId);
foreach (var chapterProgressStatus in chapterProgressStatuses)
{
…
var isChapterMustRead = IsChapterMustRead(chapterProgressStatus.ChapterId), courseSections);
…
}
…
}
public static bool IsChapterMustRead(int chapterId, IEnumerable<CourseSection> courseSections)
{
var chapterSections = courseSections.Where(cs=> cs.ChapterId == chapterId).ToList();
var initialSection = chapterSections.Single(cs=> cs.SectionId == 0);
if (initialSection.IsMustReadExempt)
{
return false;
}
return chapterSections.Any(cs=> cs.SectionId != 0 && !cs.IsMustReadExempt);
}