I was up late last night staring at execution plans. This query was the center of my attention:SELECT Branchname, CompletedUsers AS ucount, CompletedUsers * 100.0 / CASE WHEN TotalUsers = 0 THEN 1 ELSE TotalUsers END AS [Percentage Complete], TotalUsers AS [Total Users], LastCompletion AS MaxFinishDate FROM dbo.Branches B INNER JOIN ( SELECT BranchID, Count(*) AS TotalUsers, Count(CRecordFinish) AS CompletedUsers, MAX(CRecordFinish) AS LastCompletion FROM dbo.Users U LEFT OUTER JOIN ( SELECT UserID, MIN(CRecordFinish) AS CRecordFinish -- Earliest Finish time for this user on this course credit group FROM dbo.CourseRecords WHERE CRecordFinish > (SELECT CourseStartDate FROM Courses WHERE CourseID = @CourseID) AND CourseID IN (SELECT CourseID FROM dbo.UDF_CreditGroup(@CourseID)) AND ClientID = @ClientID GROUP BY UserID ) B ON B.UserID = U.UserID WHERE U.ClientID = @ClientID AND U.Inactive = 1 AND U.CenterID = @CenterID GROUP BY BranchID ) CR ON CR.BranchID = B.BranchID WHERE B.CenterID = (SELECT CenterID FROM dbo.Centers WHERE Centername = @Centername) ORDER BY [Percentage Complete] DESC, MaxFinishDate -- Order by Percentage complete, then date of completion
It took 12 seconds for this query to execute.By changing the element in red to the scalar value below, it executes in under 1 second. This surprised me because the element in red evaluates to a scalar. In other words, I replaced a scalar expression with a scalar variable.SELECT Branchname, CompletedUsers AS ucount, CompletedUsers * 100.0 / CASE WHEN TotalUsers = 0 THEN 1 ELSE TotalUsers END AS [Percentage Complete], TotalUsers AS [Total Users], LastCompletion AS MaxFinishDate FROM dbo.Branches B INNER JOIN ( SELECT BranchID, Count(*) AS TotalUsers, Count(CRecordFinish) AS CompletedUsers, MAX(CRecordFinish) AS LastCompletion FROM dbo.Users U LEFT OUTER JOIN ( SELECT UserID, MIN(CRecordFinish) AS CRecordFinish -- Earliest Finish time for this user on this course credit group FROM dbo.CourseRecords WHERE CRecordFinish > (SELECT CourseStartDate FROM Courses WHERE CourseID = @CourseID) AND CourseID IN (SELECT CourseID FROM dbo.UDF_CreditGroup(@CourseID)) AND ClientID = @ClientID GROUP BY UserID ) B ON B.UserID = U.UserID WHERE U.ClientID = @ClientID AND U.Inactive = 1 AND U.CenterID = @CenterID GROUP BY BranchID ) CR ON CR.BranchID = B.BranchID WHERE B.CenterID = @CenterID ORDER BY [Percentage Complete] DESC, MaxFinishDate -- Order by Percentage complete, then date of completion
Does anyone see a reason why the two queries should perform differently? Sam