2017-08-16 1 views
0

J'essaye d'effectuer une mise à jour groupée d'environ 200 000 lignes MySQL existantes. Plus spécifiquement, j'ai besoin de mettre à jour huit champs LONG BLOB vides dans ces lignes, chacun avec un fichier ~ 0.5 Mb (LONG BLOB est utilisé car il y a des cas particuliers où des fichiers significativement gros sont stockés, mais ceux-ci ne sont pas considérés mettre à jour). Les fichiers qui doivent être insérés sont stockés localement sur le disque. J'utilise un script MATLAB que j'ai écrit pour passer en boucle dans chacun des dossiers qui stockent ces fichiers, lire les fichiers et les convertir en représentations hexadécimales, puis exécuter une requête UPDATE pour mettre à jour les huit colonnes avec les huit fichiers pour chaque rangée. Au début, les choses tournaient assez vite; Cependant, j'ai remarqué qu'après quelques milliers de requêtes terminées, les choses ont vraiment commencé à ralentir. J'ai fait un peu de recherche sur l'optimisation des variables système MySQL et InnoDB et augmenté de innodb_buffer_pool_size à 25G et innodb_buffer_pool_instances à 25.Optimisation des performances de la mise à jour en masse de données MySQL existantes

Après cette modification, les choses ont accéléré, mais ralenti après quelques milliers de requêtes. J'ai fait un peu plus de recherche et j'ai essayé de jouer avec d'autres variables telles que innodb_log_buffer_size et innodb_log_file_size augmentant les deux à 100M juste pour voir ce qui se passerait. J'ai également mis innodb_write_io_threads et innodb_read_io_threads à 16 car je cours ceci tout sur un serveur assez haut de gamme avec 32 Go de RAM. Malheureusement, ces modifications n'ont pas aidé beaucoup et maintenant je suis coincé avec des requêtes en prenant quelques minutes chacune pour compléter.

Quelqu'un at-il des suggestions ou des idées sur la façon dont je peux optimiser ce processus et le faire fonctionner aussi vite que possible?

Merci,

Joe

+0

Le débit de votre système est limité par les opérations d'E/S (la vitesse de votre disque dur). Cela ralentit généralement l'effet des caches de lecture/écriture complets (y compris le cache de l'os qui pourrait avoir mis en cache les fichiers sources réels) - mais vous devez finalement * écrire sur le disque. Alors s'il vous plaît dites-nous la vitesse hdd, la vitesse de mise à jour (plus lente) et si les sources sont sur le même disque que la base de données pour estimer si elle est trop lente. Les choses que vous pouvez essayer: Assurez-vous que vous identifiez vos lignes avec un index (par exemple 'mise à jour ... où id = 4', clé primaire id). Commettre régulièrement, mais pas après chaque rangée; essayez par exemple toutes les 100-500 lignes. – Solarflare

+0

Hey Solarflare, nous utilisons une matrice RAID 5 de deux disques durs SAS de catégorie TB 6 To 6 Go/s à 7200 t/min qui représentent un total d'environ 36 To d'espace de stockage. Les fichiers source sont en effet sur le même espace de stockage que la base de données. Déplacer les fichiers source vers un autre espace de stockage augmenterait-il les performances? De plus, j'identifie des lignes en utilisant un index de clé primaire. – joekleespies

+0

Les spécifications du système n'aident pas beaucoup. Comparez l'E/S maxi (benchmark) aux E/S réelles. Vérifiez par exemple le moniteur de ressources pour windows ou iotop/dstat pour linux. Comparez cela à votre débit (plus lent) de mise à jour (par exemple, si vous insérez 5 lignes par seconde avec exactement 8 fois 0,5 Mo par ligne, lire et écrire est 20 Mo/s), pour vérifier si les E/S sont le goulot d'étranglement. Avoir les fichiers source sur un lecteur différent améliore la vitesse d'écriture (mais si ce n'est pas le cas, les copier d'abord devront être inclus dans le temps d'exécution). Essayez également la fréquence de validation.Aussi: peut-être juste garder les données dans le partage de système de fichiers/smb et non dans la base de données. – Solarflare

Répondre

0

innodb_buffer_pool_instances = 8 servira probablement à vos besoins avec moins de frais généraux. Innodb_log_buffer_size = 10M 'buffer' avant d'écrire dans le fichier innodb_log_file APRÈS avoir accumulé 10M dans la mémoire. Un ratio de tampon * 10 = taille du fichier journal est raisonnable.

Lorsque innodb_log_buffer_size est identique à innodb_log_file_size, vous n'avez effectivement PAS de mémoire tampon. Rend buff_size beaucoup moins que la taille du fichier journal.