Link to home
Create AccountLog in
Avatar of readyset
readyset

asked on

Query optimzation?

How can I optimize the below query especially with xmlpath subqueries that gets studentnames and studentids?

SELECT s.ID ScheduleId
		,sh.Id ShiftId
		,sh.ShiftGroupId ShiftGroupId
		,sh.ShiftName
		,sh.Code
		,sh.StartDtTm ShiftStartDate
		,sh.EndDtTm ShiftEndDate
		,COUNT(sje.StudentId) NumberFilled
		,dbo.GetTotalStudentsNeeded(sh.ID) NumberNeeded
		,sh.Note
		,sh.ShiftPublishedStateId
		,(
			SELECT e2.FirstName + ' ' + e2.LastName + '|'
			FROM Students e2
			INNER JOIN dbo.ShiftClassStudents sje2 ON e2.ID = sje2.StudentId
			INNER JOIN ScheduleShiftClasss ssj2 ON sje2.ScheduleShiftClassId = ssj2.ID
			INNER JOIN ScheduleShifts ss2 ON ssj2.ScheduleShiftId = ss2.ID
			WHERE ss2.ShiftId = sh.Id
				AND (
					ssj2.ClassId = @StudentNameClassIdFilter
					OR (
						@StudentNameClassIdFilter IS NULL
						OR @StudentNameClassIdFilter < 1
						)
					)
				AND @IncludeStudentNames = 1
			FOR XML PATH('')
			) AS StudentNames
		,(
			SELECT CAST(e2.ID AS VARCHAR(50)) + SPACE(1)
			FROM Students e2
			INNER JOIN dbo.ShiftClassStudents sje2 ON e2.ID = sje2.StudentId
			INNER JOIN ScheduleShiftClasss ssj2 ON sje2.ScheduleShiftClassId = ssj2.ID
			INNER JOIN ScheduleShifts ss2 ON ssj2.ScheduleShiftId = ss2.ID
			WHERE ss2.ShiftId = sh.Id
				AND (
					ssj2.ClassId = @StudentNameClassIdFilter
					OR (
						@StudentNameClassIdFilter IS NULL
						OR @StudentNameClassIdFilter < 1
						)
					)
				AND @IncludeStudentNames = 1
			FOR XML PATH('')
			) AS StudentIds
	FROM dbo.Schedules s
	INNER JOIN dbo.ScheduleShifts ss ON s.ID = ss.ScheduleId
	INNER JOIN dbo.Shifts sh ON ss.ShiftId = sh.Id
	LEFT OUTER JOIN dbo.ScheduleShiftClasss ssj ON ss.ID = ssj.ScheduleShiftId
	LEFT OUTER JOIN dbo.ShiftClassStudents sje ON ssj.ID = sje.ScheduleShiftClassId
	WHERE sh.StartDtTm <= @EndDate
		AND sh.StartDtTm >= @StartDate
		AND s.ID = @ScheduleID
	GROUP BY s.ID
		,sh.Id
		,sh.ShiftGroupId 
		,sh.ShiftName
		,sh.Code
		,sh.StartDtTm
		,sh.EndDtTm
		,sh.Note
		,sh.ShiftPublishedStateId

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of plusone3055
plusone3055
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
SOLUTION
Avatar of PortletPaul
PortletPaul
Flag of Australia image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
I agree with previous posts, you can actually gain a bit of performance with some change in the query.
First of all you will certainly need to check your indexes (CTRL + L in SSMS will show you the estimated execution plan with eventually missing suggested indexes).

Just as an idea...
You "may" try to extract the 2 subqueries into a different select.
Since these 2 subqueries share the same from and where, I would try to get their results in a table parameter (declare @temptab as table ...) and add that @temptable in your join.


Regards.
Avatar of readyset
readyset

ASKER

I actually gained by removing the scalar function - dbo.GetTotalStudentsNeeded(sh.ID) NumberNeeded to a table valued function. I also re-tweaked some of the indexes , the subtree cost now is 0.05 , came down from 72.08.

Thanks for your pointers.
great job!