web-dev-qa-db-fra.com

mysql dump import incroyablement lent sur la machine de mon développeur

J'ai un vidage SQL, c'est assez gros (411 Mo) et il a fallu 10 minutes pour importer sur le serveur A, la même importation sur mon poste de travail B a une estimation (pipeviewer) de 8 heures pour importer (il a importé 31 Mo en 40 minutes ) C'est donc un facteur 53 plus lent.

Les spécifications:

Server A:
   MySQL Version: 5.5.30-1.1 (Debian)
   2 GB RAM
   1 core QEMU Virtual CPU version 1.0 - cpu MHz: 3400.020

Workstation B: 
   MySQL Version: 5.5.41-MariaDB-1ubuntu0.14.04.1
   14 GB RAM
   4 cores Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz - cpu MHz: 1600.000

La configuration mysql/maria est la configuration de base.

Hier, je suis passé à MariaDB sur mon poste de travail - mais avant MariaDB, les statistiques étaient encore pires.

J'ai déjà supprimé toutes les bases de données sur mon poste de travail - aucune différence.

La grande question est: Comment les performances peuvent-elles être plus lentes de 53%? Je ne peux pas travailler comme ça :-(

Ma commande d'importation:

pv sql/master.sql | mysql -h'localhost' -u'root' -p'root' 'master'

iostat -xm 5

serveur A:

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
      17,43    0,00   30,28   51,85    0,00    0,44

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00   254,03    0,00 1305,45     0,00     6,09     9,56     0,78    0,60    0,00    0,60   0,57  74,25

poste de travail B:

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
       7,32    0,00    3,22    5,03    0,00   84,42

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     1,40    0,80  172,40     0,00     0,56     6,72     1,17    6,75   12,00    6,72   5,40  93,52

dd if=/dev/zero of=tempfile bs=1M count=1024 conv=fdatasync,notrunc

serveur A:

1073741824 bytes (1,1 GB) copied, 18,6947 s, 57,4 MB/s

poste de travail B:

1073741824 bytes (1,1 GB) copied, 8,95646 s, 120 MB/s
23
Alex

Cette réponse a beaucoup accéléré tout:

https://stackoverflow.com/a/2167641/292408

Je, simplement

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;

au début, et

COMMIT;
SET unique_checks=1;
SET foreign_key_checks=1;

à la fin.

Maintenant, cela a pris 3 minutes.

(Gracieuseté de @andreasemer via Twitter)

50
Alex

Complétant ce que je vois ci-dessus ... J'ai mon fichier de vidage déjà généré automatiquement par quelque chose comme:

mysqldump my_db > db-dump-file.sql

Je souhaite automatiser cette importation, j'ai donc créé deux fichiers sur mon ordinateur appelés default-start-import.sql et default-end-import.sql et leur contenu est default-start-import.sql:

SET autocommit=0;

et default-end-import.sql:

COMMIT;
SET autocommit=1;

et le script que je lance est quelque chose comme ça;

cat default-start-import.sql db-dump-file.sql default-end-import.sql | mysql my_other_db

même commande mais plus facile à lire:

cat default-start-import.sql \
    db-dump-file.sql \
    default-end-import.sql \
| mysql my_other_db

Dans ce cas, cat est utilisé pour concaténer ces fichiers avant de les envoyer au canal. Je pense qu'il est important que tous les fichiers se terminent par un caractère de nouvelle ligne (une ligne vide à la fin du fichier si elle est vue depuis un éditeur de texte) afin que la commande cat ne fusionne pas les lignes entre les fichiers.

L'importation fonctionne bien, je n'ai pas testé s'il est réellement plus rapide en raison de cette amélioration de la fonction d'activation et de désactivation de l'autocommit, mais si cela accélère les choses, alors ces étapes supplémentaires facilitent les choses.

5
santiago arizti

J'ai essayé --compress Ainsi que SET autocommit=0; Et ils ont aidé une petite quantité cependant ...

J'ai constaté que la conversion de plusieurs instructions INSERT INTO ... En une seule instruction de grande taille avec plusieurs VALUES(...), (...) améliorait considérablement la vitesse.

J'utilise mysql sur SSL sur WAN. La base de données MySQL distante est hébergée sur Amazon.

Avec 9 colonnes et 2100 lignes:

  • 2 100 instructions INSERT distinctes: 82s
  • 2 instructions INSERT consolidées: <1s

Avec 7 colonnes et 42 000 lignes:

  • 42 000 instructions INSERT distinctes: 1 740
  • 42 relevé consolidé INSERT: 105s

Ainsi, en fonction de l'outil générant le vidage de la base de données (ou plus précisément du format des instructions INSERT), la vitesse peut être influencée.

Remarque: Cela diminue également le fichier de vidage .sql De plus de 60% dans mes tests, ce qui économisera également sur les E/S .

Attention: Il y a limitations physiques à cette technique avec mysql et pour ceux qui ont besoin de portabilité ... SQL Serveur semble être limité à seulement 1 000 lignes à la fois.

Pourtant, faire 1 000 lignes à la fois pour 42 000 lignes donne toujours une amélioration de 1 657%!

2
tresf