2016-05-29 113 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)