任何人都可以帮我优化此查询吗?这需要15秒。如果我将WHERE子句移动到连接本身,仍然会得到相同的结果。
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;
只要这个:
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;
这是EXPLAIN结果
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
答案 0 :(得分:0)
要详尽地回答,我们需要查看您获得的EXPLAIN SELECT...(your query)
查询计划,以及已经存在的索引结构。
假设你还没有索引(除了PRIMARY KEY
之外),那就是问题,让我们看看如何掀起一些东西(可能进一步改进):
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;
JOIN
和enrollment.employeeID
之间有一个users.employeeID
子句。
所以你需要的前几个索引就在那里:
-- CREATE INDEX enrollment_ndx ON enrollment(employeeID); -- wait on this one
CREATE INDEX users_ndx ON users(employeeID);
然后WHERE
子句包含一些可以有用索引的条件。所以enrollment
的最终索引是:
CREATE INDEX enrollment_ndx ON enrollment(employeeID, number, term, status);
尝试在注册和用户上创建索引,然后重试(发布查询计划)。
注意:您还可以在查询中使用语法enrollment.status IN ('M', 'E')
来简化它。
答案 1 :(得分:0)
您需要enrollment
表上包含({至少部分)number
,term
和status
的索引。您还需要employeeID
上的employees
索引(如果它不是主键,它应该是主键)。
CREATE INDEX idx1 ON enrollment (number, term, status);
CREATE INDEX idx2 ON users (employeeID); // if needed
这将确保mysql首先使用索引在enrollment
表中查找并再次加入users
表。