it-swarm.com.de

MySQL wählen, wo nicht in der Tabelle

Ich habe 2 Tabellen (A und B) mit den gleichen Primärschlüsseln. Ich möchte alle Zeilen auszuwählen, die in A sind und nicht in B. folgenden Arbeiten:

select * from A where not exists (select * from B where A.pk=B.pk);

es scheint jedoch ziemlich schlecht zu sein (~ 2 Sek. in nur 100k Zeilen in A und 3-10k weniger in B)

Gibt es einen besseren Weg, dies zu laufen? Vielleicht als Linke mitmachen?

select * from A left join B on A.x=B.y where B.y is null;

Auf meinen Daten scheint dies etwas schneller zu laufen (~ 10%), aber was ist in der Regel?

52
BCS

Ich benutze Abfragen im Format Ihrer zweiten Beispiel. Ein Join ist normalerweise skalierbarer als eine korrelierte Unterabfrage.

35
Bill Karwin

Ich denke, Ihre letzte Aussage ist der beste Weg. Sie können es auch versuchen

SELECT A.*    
from A left join B on 
    A.x = B.y
    where B.y is null
55
Nick Berardi

Joins sind in der Regel schneller (in MySQL), Sie sollten jedoch auch Ihr Indizierungsschema berücksichtigen, wenn Sie feststellen, dass es sich immer noch langsam bewegt. Im Allgemeinen als Fremdschlüssel (mit INNODB) alle Felder Setup wird bereits einen Index gesetzt haben. Wenn Sie MYISAM verwenden, stellen Sie sicher, dass alle Spalten in der ON-Anweisung indiziert sind, und denken Sie daran auch das Hinzufügen aller Spalten in der WHERE-Klausel am Ende des Index, macht es zu einem abdeckenden Index. Auf diese Weise kann die Suchmaschine auf alle im Index benötigten Daten zugreifen, sodass kein zweiter Roundtrip zu den ursprünglichen Daten erforderlich ist. Denken Sie daran, dass dies die Geschwindigkeit der Einsätze/Aktuelles/Löschungen auswirken, sondern die Geschwindigkeit der Abfrage erheblich erhöhen kann.

2
ChoNuff

Ich verwende auch Left-Joins mit einem Kriterium vom Typ "where table2.id is null".

Scheint sicherlich effizienter zu sein als die Option für verschachtelte Abfragen.

2
Dave Rix