2011-01-13 4 views
5

Supposons que j'ai une table avec deux colonnes A et B. Il y a un index sur la colonne A, mais pas sur la colonne B. Je veux émettre plusieurs millions de requêtes comme:MySQL UPDATE optimisation?

UPDATE t1 SET b=b1 WHERE a=a1; 
UPDATE t1 SET b=b2 WHERE a=a2; 
.... 

Il y a partout de 1 à 100 000 lignes correspondant à chaque valeur unique de a. En moyenne, il est autour de 100.

Pour chaque instruction de mise à jour en moyenne 60% des lignes ne seront pas modifiées car pour ces lignes b a déjà la valeur désirée. Pour 30% des mises à jour, aucune des lignes correspondantes ne sera modifiée.

Est-il sensé d'utiliser des instructions comme celles-ci?

UPDATE t1 SET b=b1 WHERE a=a1 AND b<>b1; 

aura-t-il SpeedUp le processus en éliminant les réécritures non nécessaires sur le disque ou est Mysql 5 assez intelligent pour reconnaître que rien n'est changé et il n'y a pas besoin d'écrire sur le disque?

Répondre

4

Dans les deux cas, MySQL vais devoir lire la le contenu de la ligne (que ce soit sur le disque ou dans un cache/pool de mémoire tampon). Dans les deux cas, MySQL utilisera votre index sur a comme point de départ. Dans les deux cas, MySQL ne mettra pas à jour la ligne si elle a déjà la valeur de destination b. Par conséquent, je ne vois pas comment MySQL pourrait bénéficier de la clause b<>b1.

On peut dire que, en fonction de la charge de travail et ensemble de données, la requête (avec b<>b1 en elle) pourrait avantage si vous changez votre index sur a être un indice composé sur a et b (dans cet ordre). Dans ce cas, il n'aura pas à frapper le disque (ou vérifier le cache/pool de mémoire tampon) pour trouver quelles lignes spécifiquement nécessitent une mise à jour (c'est-à-dire que vous capitaliseriez sur les 30% et 60% mentionnés). Cela dit, maintenant votre index nécessitera une mise à jour pour chaque mise à jour sur b, donc est un coût, même si je soupçonne que le compromis pourrait en valoir la peine.

0

Vous devez ajouter le filtre supplémentaire. Mysql est assez intelligent pour ne pas mettre à jour une valeur si c'est la même chose, mais il est préférable d'éliminer cette vérification. Vous pouvez le confirmer en voyant combien de lignes ont été "affectées" par la requête.

0

Je pensais à combiner plusieurs mises à jour en mise à jour unique à l'aide CASE

update t1 
set b= 
    case a 
    when a=a1 then b1 
    when a=a2 then b2 
    when a=a3 then b3 ... 
    end; 

espoir ce utile, et si elle horrible lente, s'il vous plaît inclure explaination