2010-03-19 3 views
5

Salut J'ai le T tableau suivant:alternative à « où col dans (liste) » pour MySQL

id 1 2 3 4 
col a b a c 

Je veux faire une sélection qui retourne l'id, col en groupe par (col) nombre ayant (col)> 1

une façon de le faire est

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

le stagiaire de sélection (à droite) a 'rendements et principal (à gauche) retourne 1, a et 3, un

Le problème est que l'instruction where in est extrêmement lente. Dans mon cas réel, les résultats de la sélection interne a beaucoup de «col», quelque chose à propos de 70000 et cela prend des heures.

En ce moment, il est beaucoup plus rapide de faire la sélection interne et la sélection principale obtenant tous les ids et upcs et faire l'intersection localement. MySQL devrait être capable de gérer efficacement ce type de requête. Est-ce que je peux substituer l'où dans une jointure ou quelque chose de plus rapide?

Merci

Répondre

5

Vous pouvez essayer si vous utilisez un INNER JOIN vitesses choses

  • Assurez-vous que vous avez un index sur col
  • Un indice de couverture sur col, id pourrait vous gagner encore de meilleures performances

Déclaration SQL

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

Merci. Cela a bien fonctionné. J'ai inséré avant de tcol le mot-clé 'as'. Je n'ai même pas d'index sur col, mais ça a marché très vite. – 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 
     ) 

Assurez-vous que vous avez un index sur (col) (en InnoDB) ou (col, id) (en MyISAM)

La requête interne arrêtera l'évaluation dès qu'il trouve une première valeur correspondante. Avec un index, cela se produira après un seul index avec au plus deux index.

+0

+1. Peut-être pourriez-vous ajouter quelques explications sur * pourquoi * c'est * beaucoup * plus rapide que les OP ou ma solution. Je suppose qu'il s'agit de ne pas avoir à balayer un index entier et de pouvoir s'arrêter quand une correspondance a été trouvée. –

Questions connexes