2016-05-29 116 views
0

我无法将我的SQL查询转换为更高性能的JOIN查询。下面是该查询MySQL JOIN替换子查询(OR NOT IN)

SELECT * FROM `Link` 
WHERE idConceptStart = 31 AND flag = 0 AND (
    idConceptLink IN (
     SELECT idConceptStart FROM Link 
     WHERE idConceptTarget = 13 
     AND idConceptLink IN (11, 315) 
    ) 
    OR idConceptLink NOT IN ( 
     SELECT idConceptStart FROM `Link` WHERE idConceptLink IN (11, 315) 
    ) 
) 

我设法返回查询

SELECT * FROM `Link` l 
JOIN `Link` j ON l.idConceptLink = j.idConceptStart 
LEFT JOIN Link k ON k.idConceptStart = l.idConceptLink 

WHERE l.idConceptStart = 31 
AND j.flag = 0 AND j.idConceptTarget IN(13) 
AND j.idConceptLink IN (11, 315) 
AND k.idConceptLink IN (11, 315) AND k.flag != 1107 
AND l.flag = 0 
AND k.`idConceptStart` IS NULL 

的第一部分,但我没有得到第二部分

OR idConceptLink NOT IN (SELECT idConceptStart FROM `Link` WHERE idConceptLink IN (11, 315)) 

用我的左连接添加我没有得到任何结果

我该如何管理?我试着也使使用UNION更换或其他查询,但我不能设法让这个查询

+0

这个'AND k.flag!= 1107'从哪里来? – EagleRainbow

+0

这个'OR idConceptLink'不能用'JOIN'表示。将逻辑“OR”表达式转换为set操作的世界更像是“UNION”操作符。你想摆脱所有的子查询,还是只想让查询性能更好? – EagleRainbow

+0

其实我希望查询性能更好。 在我的情况下,k.flag!= 1107与flag = 0相同 – user3032887

回答

0

请给

SELECT * FROM `Link` l 
inner join 
(
    select idConceptStart FROM `Link` 
    WHERE idConceptLink NOT IN (11, 315) 
     OR (idConceptTarget = 13 AND idConceptLink IN (11, 315)) 
) as secondCondition 
on l.idConceptLink = secondCondition.idConceptStart 

WHERE l.idConceptStart = 31 AND l.flag = 0 

一试。你的问题既复杂又抽象,如果你不明白这些属性的背后是什么(你在这里涉及到一些“神奇数字”)。

如果对您而言查询仍然显得太慢,请在其前面输入EXPLAIN并将结果发布以供进一步分析。

0

为了提高性能,您将需要重写查询并创建索引。我会建议使用not existsexists,而不是in

SELECT l.* 
FROM `Link` l 
WHERE idConceptStart = 31 AND flag = 0 AND (
     (EXISTS (SELECT 1 
       FROM link l2 
       WHERE l.idConceptLink = l2.idConceptStart AND 
        l2.idConceptTarget = 13 AND l2.idConceptLink IN (11, 315) 
      ) OR 
     NOT EXISTS (SELECT 1 
        FROM link l2 
        WHERE l.idConceptLink = l2.idConceptStart AND 
         l2.idConceptLink IN (11, 315) 
       ) 
    ); 

对于此查询,您想对指数:link(idConceptStart, flag)link(idConceptStart, idConceptTarget, idConceptLink)link(idConceptStart, idConceptLink)