2016-05-29 8 views
0

Ich habe Probleme, meine SQL-Abfrage in eine JOIN-Abfrage zu transformieren, die viel performanter ist. Hier ist die AbfrageMySQL JOIN zum Ersetzen von Unterabfragen (ODER NICHT 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) 
    ) 
) 

schaffe ich den ersten Teil der Abfrage zurück

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 

Aber ich bin es nicht die zweite Teil

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

Mit meinem linken bekommen join hinzugefügt Ich erhalte keine Ergebnisse

Wie kann ich das schaffen? Ich habe auch versucht, eine andere Abfrage mit der UNION zu machen, die OR zu ersetzen, aber ich kann nicht diese Abfrage geben

+0

Woher kommt dieses 'UND k.flag! = 1107'? – EagleRainbow

+0

Dieser 'OR idConceptLink' kann nicht mit' JOIN' ausgedrückt werden. Das Übersetzen logischer OR-Ausdrücke in die Welt der Mengenoperation ähnelt eher den UNION-Operatoren. Möchten Sie alle Unterabfragen loswerden oder möchten Sie nur, dass Ihre Abfrage besser abschneidet? – EagleRainbow

+0

Eigentlich möchte ich, dass die Abfrage besser abschneidet. k.flag! = 1107 in meinem Fall ist das gleiche als flag = 0 – user3032887

Antwort

0

Bitte

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 

einen Versuch zu machen, verwalten. Ihre Frage ist sowohl ziemlich kompliziert als auch abstrakt, wenn Sie nicht verstehen, was hinter all diesen Attributen steckt (Sie haben hier einige "magische Zahlen").

Wenn die Abfrage immer noch zu langsam für Sie erscheint, legen Sie bitte eine EXPLAIN vor und veröffentlichen das Ergebnis zur weiteren Analyse.

0

Um die Leistung zu verbessern, müssen Sie die Abfrage neu schreiben und Indizes erstellen. Ich würde empfehlen, not exists und exists, anstatt 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) 
       ) 
    ); 

Für diese Abfrage möchten Sie Indizes für: link(idConceptStart, flag), link(idConceptStart, idConceptTarget, idConceptLink) und link(idConceptStart, idConceptLink).

Verwandte Themen