In this post, I will discuss on how to optimize join. Based on my experience. When you join record you need to join as fewer as possible otherwise it will result in performance. And please make sure you put the index on the key that you are using for join.
Within SQL Server 2005, You can use temporary view, It is not a table variable and it is not a temporary table. You also need to try to avoid cursor as well if possible.
First sample is a traditional join where I joined all the tables that required. In this sample EvenResult table has 20 million rows and I need to count the evenresult table based on the EventID that I get from the join criteria.
1. Join all tables./Traditional Way and it takes about 21secs
SELECT
E.EventID
FROM
Events E
INNER JOIN
Venues V
ON
E.VenueID = V.VenueID
INNER JOIN
Regions R
ON
R.RegionID = V.RegionID
INNER JOIN
EventResults er
ON
E.EventID = er.EventID
WHERE
(DATEDIFF(d, E.EventDate, @DateFrom) = 0)
AND
((@StateID IS NULL) OR (R.StateID = @StateID))
AND
((@RegionID IS NULL) OR (R.RegionID = @RegionID))
AND
((@VenueID IS NULL) OR (V.VenueID = @VenueID))
AND
((@EventScheduleID IS NULL) OR (E.EventScheduleID = @EventScheduleID))
2. Using Temporary Views, In this query. I try to filter down all the required eventID based on the criteria and insert it into a temporary view(tblEvents). Once i get the filtered result then I joined it with EventResults table and It takes only 16secs considering the number of records.
WITH tblEvents(EventID) AS
(
SELECT
E.EventID
FROM
Events E
INNER JOIN
Venues V
ON
E.VenueID = V.VenueID
INNER JOIN
Regions R
ON
R.RegionID = V.RegionID
WHERE
(DATEDIFF(d, E.EventDate, @DateFrom) = 0)
AND
((@StateID IS NULL) OR (R.StateID = @StateID))
AND
((@RegionID IS NULL) OR (R.RegionID = @RegionID))
AND
((@VenueID IS NULL) OR (V.VenueID = @VenueID))
AND
((@EventScheduleID IS NULL) OR (E.EventScheduleID = @EventScheduleID))
)
SELECT
COUNT(*) As Total
FROM
tblEvents te
INNER JOIN
EventResults er
ON
te.EventID = er.EventID
GROUP BY
er.MemberID
HAVING
COUNT(*) >= @MinGame
AND
COUNT(*) <= @MaxGame
Leave a Reply