此查询显示正确的结果,但在执行 EXPLAIN 时,它将其列为“依赖子查询”,我认为这是不好的?
SELECT Competition.CompetitionID, Competition.CompetitionName, Competition.CompetitionStartDate
FROM Competition
WHERE CompetitionID NOT
IN (
SELECT CompetitionID
FROM PicksPoints
WHERE UserID =1
)
我尝试将查询更改为:
SELECT Competition.CompetitionID, Competition.CompetitionName, Competition.CompetitionStartDate
FROM Competition
LEFT JOIN PicksPoints ON Competition.CompetitionID = PicksPoints.CompetitionID
WHERE UserID =1
and PicksPoints.PicksPointsID is null
但它显示 0 行。与第一个实际有效的查询相比,上述内容有什么问题?
最佳答案
秒查询无法生成行:它声称:
WHERE UserID =1
and PicksPoints.PicksPointsID is null
但为了澄清,我重写如下:
WHERE PicksPoints.UserID =1
and PicksPoints.PicksPointsID is null
因此,一方面,您要求在 PicksPoints
上查找 UserId = 1
上的行,但您又希望该行一开始就不存在。你能看到失败吗?
外部连接是如此棘手!通常,您使用“外部”表中的列进行过滤,例如Competition
。但你不希望这样做;您希望在左连接表上进行过滤。尝试重写如下:
SELECT Competition.CompetitionID, Competition.CompetitionName, Competition.CompetitionStartDate
FROM Competition
LEFT JOIN PicksPoints ON (Competition.CompetitionID = PicksPoints.CompetitionID AND UserID = 1)
WHERE
PicksPoints.PicksPointsID is null
有关此内容的更多信息,请阅读此 nice post .
但是,作为补充说明,在性能方面,使用子查询或左连接会遇到一些麻烦。
使用子查询你会遇到麻烦,因为直到5.6(已经做了一些很好的工作),MySQL 在优化内部查询方面非常糟糕,并且你的子查询预计会执行多次。
使用LEFT JOIN
,您会遇到麻烦,因为LEFT JOIN
规定了从左到右的连接顺序。然而,您的过滤位于右侧的表上,这意味着您将无法使用索引来过滤 USerID = 1
条件(或者您会这样做,并丢失连接的索引)。
关于mysql - 依赖子查询 v 左连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11589386/