2009-08-12 12 views
2

Ich habe eine Tabelle namens Benutzer mit etwa 250.000 Datensätze darin. Ich habe eine andere Tabelle namens Staging mit rund 75.000 Datensätzen. Staging hat nur eine Spalte, msisdn. Ich möchte überprüfen, wie viele Zeilen in der Staging nicht vorhanden in Benutzern sind.MySQL JOIN Query, die viel zu lange dauert zu vervollständigen

Ich habe die folgende Abfrage, die ich auf einem kleinen Teildatenmenge getestet haben, und es scheint gut zu funktionieren:

SELECT 
    s.* 
    FROM staging s 
     LEFT OUTER JOIN users u ON u.msisdn=s.msisdn 
     WHERE u.msisdn IS NULL 

Das Problem jedoch ist, wenn ich versuche, diese Abfrage auf die volle Liste zu laufen von 250k Benutzern. Es lief für eine Stunde, bevor ich es aufhörte. Gibt es eine Möglichkeit, diese Abfrage zu optimieren?

SELECT 
    s.* 
    FROM staging s 
     LEFT OUTER JOIN users u ON u.msisdn=s.msisdn 
     WHERE u.msisdn IS NULL 
    LIMIT 0,10000 

msisdn ist der Primärschlüssel der Staging-Tabelle, aber es ist nicht der Primärschlüssel der Tabelle: die Abfrage auf Teilmengen der Daten in Staging ausgeführt wird, aber das ist schrecklich manuelles

Ich habe begonnen Benutzer. Ich weiß nicht, ob das wichtig ist.

+0

Bitte führen Sie Ihre Anfrage durch EXPLAIN und veröffentlichen Sie das Ergebnis. Sind beide msisdn Spalten indiziert? Wenn dies der Fall ist, führen Sie OPTIMIZE TABLE für beide Tabellen aus. –

Antwort

4

Zuerst können Sie sehen, welche Indizes MySQL mit dem Befehl EXPLAIN verwendet. Schreiben Sie einfach EXPLAIN vor Ihre Abfrage, und die Ergebnisse zeigen, welchen Index (falls vorhanden) es verwendet. Vermutlich ist es so langsam bei so (relativ) kleinen Datensätzen wie 250.000 Datensätzen, es nutzt nicht einen sehr effektiven Index, und Sie werden sehen können, wo.

Es kann auch helfen, die Abfrage als NOT EXISTS wie so zu umschreiben:

SELECT s.* FROM staging s 
WHERE NOT EXISTS (SELECT 1 FROM users WHERE users.misdn = s.misdn) 
1

Setzen Sie Indizes auf die msisdn Spalten jeder Tabelle. Da es keine PK unter users ist, müssen Sie einen nicht gruppierten Index darauf setzen. Das sollte Ihre Anfrage enorm beschleunigen.

0

Ich bin mir nicht sicher, wie viel schneller das sein wird, aber Sie können etwas wie versuchen.

select msisdn 
from staging 
where msisdn not in (select msisdn from users) 

Stellen Sie außerdem sicher, dass für die Spalte msisdn in beiden Tabellen ein Index vorhanden ist. Das sollte die Dinge enorm beschleunigen.

1

Dinge, die Sie diese Abfrage beschleunigen tun können:

  • sicher msisdn machen, ist in beiden Tabellen indiziert
  • optimieren Ihre Tabellen
  • ersetzen * mit msisdn