我已经进行了广泛的搜索并通过研究提高了性能,但是我仍然没有获得我认为可能的最快结果。
我有以下SQL:
SELECT x.`level`, count(x.`level`) AS TOTAL FROM (
SELECT a.`level` FROM `gharaffa`.`wwlassessments` a
LEFT JOIN `gharaffa`.`users` u on u.`pupilID` = a.`pupilID`
WHERE a.`dateAchieved` = (
SELECT MAX(a2.`dateAchieved`)
FROM `gharaffa`.`wwlassessments` a2
WHERE a.`pupilID`= a2.`pupilID` && a2.`id`='867' && u.form='Y02GA' && u.enrolled='1' )
)x
GROUP BY x.`level`
它在1.8秒内在我的50,000行的表上执行。
但是,页面将使用不同的参数运行此查询60次。
这花了太长时间。
本来我有这部分:
u.form ='Y02GA'&& u.enrolled ='1'
在联接之外花费了4.20秒。...我将时间减少了一半以上,但我不禁认为它仍然没有达到应有的效率。
感激任何指针。
约翰 :-)
最佳答案
这是您的查询:
SELECT x.level, count(x.level) AS TOTAL
FROM (SELECT a.level
FROM gharaffa.wwlassessments a LEFT JOIN
gharaffa.`users` u
on u.`pupilID` = a.`pupilID`
WHERE a.dateAchieved = (SELECT MAX(a2.dateAchieved)
FROM gharaffa.wwlassessments a2
WHERE a.pupilID = a2.pupilID AND
a2.id = 867 AND
u.form = 'Y02GA' AND
u.enrolled = 1
)
) x
GROUP BY x.level;
该查询似乎过于复杂。请注意两个小变化:
删除数字常量周围的单引号。不要对数字值使用单引号(我假设
id
是数字)。将
&&
更改为AND
。后者是标准SQL。一些观察:
最里面的子查询将
LEFT JOIN
转换为INNER JOIN
。u
上的条件应位于中间的WHERE
,而不是最内部的WHERE
。不需要外部子查询。
因此,我将其写为:
SELECT a.level, COUNT(*) as TOTAL
FROM gharaffa.wwlassessments a JOIN
gharaffa.users u
ON u.pupilID = a.pupilID
WHERE u.form = 'Y02GA' AND
u.enrolled = 1 AND
a.dateAchieved = (SELECT MAX(a2.dateAchieved)
FROM gharaffa.wwlassessments a2
WHERE a.pupilID = a2.pupilID AND
a2.id = 867
)
GROUP BY a.level;
为此,您需要在
users(form, enrolled, pupilID)
和wwlassessments(pupilId, id, level)
上建立索引。关于mysql - 左联接的效率,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42762152/