2011-05-19 3 views
2

J'ai deux tables Shere:besoin de mettre à jour une table MySQL avec des millions de lignes

Cities 
Region| City Name 

States 
ID| State | Region_Key 

que je dois faire une requête de mise à jour sur la table des villes comme si cities.region = définir-à-dire où les États statres.id .region_key = cities.region

Le problème est que la base de données des villes a plus de 2,7 millions d'enregistrements et j'ai essayé de faire une requête comme celle-ci pour que mysql se bloque et disparaisse.

update cities c, states c set c.region = s.id where c.region = s.region_key 

EDIT ===================

C'est le sql J'utilise mais son travail ne je reçois une erreur disant que l'utilisation incorrecte de Mise à jour et LIMIT

update cities w, states s 
set w.region_id = s.id, 
w.updated = 1 
where w.region = s.w_code and w.updated = 0 
LIMIT 10000 
+1

rupture en lots, en utilisant peut-être une autre colonne (comme un datetime), ou si non approprié introduire un row_number() –

+0

Vous utilisez l'alias "c" deux fois, pour chaque table – bart

Répondre

2
  1. Ajouter une colonne de bits annulable [HasBeenUpdated] à la table cities
  2. Ajouter Set c.HasBeenUpdated = 1 à la clause de mise à jour
  3. Ajouter les éléments suivants lorsque la condition AND c.HasBeenUpdated IS NULL
  4. Ajouter un nouveau WHERE condition AND c.ID in (Select ID from Cities where HasBeenUpdated Is Null Limit 10000). Cela est nécessaire car vous ne pouvez pas utiliser une instruction Limit sur un multi-table Update (source). Cela suppose également que vous ayez une colonne ID comme PK pour les villes (si ce n'est pas le cas, pensez à en ajouter une). Maintenant, l'instruction update ne traitera que 10 000 lignes à la fois (et traitera uniquement les lignes non traitées).

Si vous pouvez mettre ceci dans une boucle en utilisant votre logique d'application, cela peut être utilisé pour l'automatisation. Modifiez le nombre limite en fonction de vos besoins et lorsque cela est fait, supprimez la colonne HasBeenUpdated. Ceci devrait vous permettre de minimiser l'impact de la mise à jour sur la table et la base de données, et vous permettre de l'exécuter sur l'ensemble de la table par lots gérables.

Modifier: Mettre à jour l'étape 4 pour filtrer les lignes à mettre à jour via la sous-requête, car une instruction Limit ne peut pas être utilisée sur une mise à jour multi-tables.

+0

vous voulez dire 'OERE c.hasBeenUpdated EST NULL', sûrement? – Piskvor

+0

Ne fonctionne pas :(Je reçois un message erorr Mauvaise utilisation de UPDATE et LIMIT, j'utilise deux tables ici – Ali

+0

S'il vous plaît vérifier ma question mise à jour ... – Ali

1

Utilisez SELECT INTO NEW_TABLE pour créer une nouvelle table avec le contenu désiré, puis déposer/renommer la table ancienne et utiliser RENAME TABLE pour renommer la table créé newely en nom propre:

CREATE TABLE new_cities SELECT 
    states.id AS region_id, cities.name 
FROM cities JOIN states ON cities.region = states.w_code; 

RENAME TABLE cities TO old_cities, new_cities TO cities; 
Questions connexes