我已经进行了广泛的搜索并通过研究提高了性能,但是我仍然没有获得我认为可能的最快结果。

我有以下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/

10-11 09:12