Can anyone help me optimize this query? It takes 15 seconds. If I move the WHERE clauses up to the join itself, still the same result.
SELECT
`users`.`employeeID` as `username`,
`users`.`firstName` as `fname`,
`users`.`lastName` as `lname`
FROM `enrollment`
INNER JOIN `users` ON `enrollment`.`employeeID` = `users`.`employeeID`
WHERE `enrollment`.`number` = [int]
AND
`enrollment`.`term` = [int]
AND
(
`enrollment`.`status` = 'E'
OR
`enrollment`.`status` = 'M'
)
ORDER BY
`users`.`lastName` ASC,
`users`.`firstName` ASC;
Takes as long as this:
SELECT
`users`.`employeeID` as `username`,
`users`.`firstName` as `fname`,
`users`.`lastName` as `lname`
FROM `enrollment`
INNER JOIN
`users` ON `enrollment`.`employeeID` = `users`.`employeeID`
AND
`enrollment`.`number` = [int]
AND
`enrollment`.`term` = [int]
AND
(
`enrollment`.`status` = 'E'
OR
`enrollment`.`status` = 'M'
)
ORDER BY
`users`.`lastName` ASC,
`users`.`firstName` ASC;
This is the EXPLAIN results
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users ALL PRIMARY NULL NULL NULL 52925 Using filesort
1 SIMPLE enrollment ref employeeID,number_term employeeID 9 ezlrn.users.employeeID 2 Using where
To answer exhaustively we would need to check out the query plan, which you obtain issuing an
EXPLAIN SELECT...(your query), and the index structure already in place.In the hypothesis that you have no indexes yet (except maybe the
PRIMARY KEYones), and that is the problem, let’s see how to whip up something (possibly further improveable):You have a
JOINclause beetweenenrollment.employeeIDandusers.employeeID.So the first couple of indexes you need is right there:
Then the
WHEREclause contains some more conditions that can be usefully indexed. So the final index forenrollmentwould be:Try creating the indexes on enrollment and users, and try again (posting the query plan).
Note: you can also use the syntax
enrollment.status IN ('M', 'E')in your query to simplify it.