2009-08-17 7 views
2

J'ai ajouté un champ à une table MySQL. J'ai besoin de remplir la nouvelle colonne avec la valeur d'une autre table. Voici la requête que je voudrais courir:Exécuter la requête de mise à jour MySQL sur 750k lignes

UPDATE  table1 t1 
SET   t1.user_id = 
         (
         SELECT t2.user_id 
         FROM  table2 t2 
         WHERE t2.usr_id = t1.usr_id 
         ) 

j'ai couru cette requête localement sur 239K lignes et il a fallu environ 10 minutes. Avant de faire cela sur l'environnement en direct, je voulais demander si ce que je fais semble ok, c'est-à-dire 10 minutes sonnent raisonnable. Ou devrais-je le faire d'une autre manière, une boucle php? une meilleure requête?

Répondre

6

Utilisez un UPDATE JOIN! Cela vous fournira un inner join natif pour mettre à jour, plutôt que d'exécuter la sous-requête pour chaque ligne sanglante. Il tend à être beaucoup plus vite.

update table1 t1 
inner join table2 t2 on 
    t1.usr_id = t2.usr_id 
set t1.user_id = t2.user_id 

Assurez-vous que vous avez un index sur chacune des colonnes usr_id aussi. Cela va accélérer les choses un peu.

Si vous avez des lignes qui ne correspondent pas et que vous souhaitez définir t1.user_id = null, vous devez effectuer un left join au lieu d'un inner join. Si la colonne est déjà null, et que vous cherchez simplement à la mettre à jour avec les valeurs t2, utilisez un inner join, car c'est plus rapide.

Je devrais mentionner, pour la postérité, qu'il s'agit de la syntaxe MySQL seulement. Les autres SGBDR ont différentes façons de faire un update join.

+1

Cette requête nécessite un 'LEFT JOIN 'pour produire les mêmes résultats (c'est-à-dire' NULL's dans les rangées absentes) – Quassnoi

+0

wow! testé la requête sur 100 lignes - avg 650ms. Création de la clé d'index MUL sur usr_id sur les deux tables 100 lignes moyennes 7ms! – ed209

+0

@ ed209: C'est incroyable l'impact que de petits changements peuvent avoir, hein? – Eric

0

Il y a deux pièces assez importantes d'informations manquantes:

  1. Quel type de tables sont-ils?
  2. Quels index existent sur eux?

Si table2 a un index qui contient user_id et usr_id comme les deux premières colonnes et table1 est indexé sur user_id, il ne devrait pas être si mauvais.

0

Vous n'avez pas d'index sur t2.usr_id.

Créez cet index et réexécutez votre requête, ou une table multiple UPDATE proposée par @Eric (avec LEFT JOIN, bien sûr).

Notez que MySQL manque d'autres méthodes JOIN que NESTED LOOPS, donc c'est l'index qui compte, pas la syntaxe UPDATE.

Cependant, la table multiple UPDATE est plus lisible.

Questions connexes