2010-03-19 4 views
5

Hallo Ich habe die folgende Tabelle T:Alternative zu ‚wo col in (Liste)‘ für MySQL

id 1 2 3 4 
col a b a c 

ich wählen tun möchten, dass die ID zurückgibt, col, wenn die Gruppe von (col) mit Graf (col)> 1

eine Möglichkeit, es zu tun ist

SELECT id,col FROM T 
    WHERE col IN (SELECT col FROM T GROUP BY(col) HAVING COUNT(col)>1); 

der Praktikant select (von rechts) gibt 'a' und Haupt (links) gibt 1 zurück, a und 3, ein

Das Problem ist, dass die Where in-Anweisung extrem langsam zu sein scheint. In meinem realen Fall haben die Ergebnisse von der internen Auswahl viele 'Col's, etwas über 70000 und es dauert Stunden.

Im Moment ist es viel schneller, die interne Auswahl und die Hauptauswahl alle IDs und UPCs zu bekommen und die Kreuzung lokal zu machen. MySQL sollte diese Art von Abfragen effizient verarbeiten können.

Kann ich das Wo für einen Join oder etwas schneller ersetzen?

Dank

Antwort

5

Sie könnten versuchen,

  • Achten Sie darauf, einen Index auf col
  • Ein abdeckenden Index auf col, id könnte gewinnen Sie eine noch bessere Leistung eine innere Geschwindigkeiten Dinge JOIN, wenn mit

SQL-Anweisung

SELECT T.id, T.col 
FROM T 
     INNER JOIN (
      SELECT col 
      FROM  T 
      GROUP BY col 
      HAVING COUNT(*) > 1 
     ) tcol ON tcol.col = T.col 
+0

Danke. Das hat gut funktioniert. Ich habe vor tcol das Schlüsselwort 'as' eingefügt. Ich habe nicht einmal einen Index für col, aber es hat sehr schnell funktioniert. – duduklein

2
SELECT id, col 
FROM t t1 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM t t2 
     WHERE t2.col = t1.col 
       AND t2.id <> t1.id 
     ) 

Achten Sie darauf, einen Index für (col) (in InnoDB) oder (col, id) (in MyISAM)

Die innere Abfrage Auswertung wird aufhören, sobald sie einen ersten Anpassungswert findet. Bei einem Index erfolgt dies nach einer einzigen Indexsuche mit höchstens zwei Index-Scans.

+0

+1. Vielleicht könnten Sie eine Erklärung hinzufügen, warum * das * viel * schneller ist als bei OP oder meiner Lösung. Ich nehme an, es hat damit zu tun, dass man nicht einen ganzen Index scannen muss und stoppen kann, wenn eine Übereinstimmung gefunden wurde. –