2014-07-19 3 views
0

Donc à des fins de développement, j'ai besoin d'avoir une table avec environ 1 million à 100 millions de valeurs, ma méthode actuelle n'est pas rapide du tout.MySQL - Comment insérer rapidement des millions de lignes?

Qu'est-ce que les développeurs font habituellement pour avoir leurs tables avec des millions de lignes pour tester la vitesse à laquelle leur programme peut les gérer?

Ma méthode actuelle est de 10 pour les boucles, mais c'est vraiment lent pour la quantité de lignes dont j'ai besoin.

Alors, que puis-je faire pour insérer des millions de lignes rapidement ?, Que font les développeurs professionnels dans ce cas?

+0

http://stackoverflow.com/q/1626059/40822 – dotjoe

+0

@dotjoe Je n'ai pas de fichier à charger dedans:/ – Debels

+2

Vous pouvez générer les données dans un fichier, puis les utiliser pour les charger dans une base de données plusieurs fois. – dotjoe

Répondre

1

Généralement, la partie la plus lente d'une insertion met à jour les index. Pour accélérer les insertions de masse, désactivez les index, envoyez les insertions, puis réactivez-les.

Utilisez également l'une des syntaxes à insertion multiple plutôt que d'émettre une instruction INSERT pour chaque ligne individuelle.

+0

Comment désactiver les index ?, Je suppose que son ALTER TABLE tbl_name DISABLE KEYS? – Debels

+0

ne pas désactiver les index, utilisez la commande LOAD DATA –

1

Je suppose que vous insérez vos dossiers comme ci-dessous:

INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 

Utilisez plutôt ceci:

INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"), 
               ("data1", "data2"), 
               ("data1", "data2"), 
               ("data1", "data2"), 
               ("data1", "data2"); 

Note: Pour optimiser la vitesse d'insertion, combinent de nombreuses petites opérations en une seule grande opération. Idéalement, vous faites une seule connexion, envoyez les données pour plusieurs nouvelles lignes à la fois, et retardez toutes les mises à jour de l'index et la vérification de la cohérence jusqu'à la fin.

1
  1. script écriture pour générer des données
  2. sortie Permet d'insérer dans la base de données
  3. Il suffit de lancer la nuit
  4. Profitez de cette pinte quand il fait son truc
1

On ne sait pas de votre question Quelle est la nature des données que vous devez insérer, mais si elle peut être générée à la volée que le moyen le plus rapide possible est de faire en une seule requête (qui va insérer 1m de clients) comme ceci

INSERT INTO customers (id, customer_name) 
SELECT n, CONCAT('Customer', n) 
    FROM 
(
select a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + f.N * 100000 + 1 N 
from (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) a 
     , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) b 
     , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) c 
     , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) d 
     , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) e 
     , (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) f 
) t 

Voici SQLFiddle démo pour 10k lignes

Lectures recommandées:

1

La solution la plus rapide est de ne pas charger les données du tout, mais commence par une pré-pop répertoire de données ulated.

Si vous initialisez simplement des données pour le développement/test, ne chargez pas les données du tout. Démarrez une nouvelle instance de MySQL à partir d'une sauvegarde physique.

Vous pouvez utiliser Percona XtraBackup pour effectuer une sauvegarde physique de toute instance MySQL en cours d'exécution sans bloquer le trafic.

Préparez ensuite la sauvegarde, et il est immédiatement utilisable en tant que répertoire de données en direct.

Ensuite, vous pouvez obtenir une nouvelle instance de test configurée aussi rapidement que vous pouvez exécuter cp pour copier ce répertoire de données et lancer une instance de mysqld, en spécifiant --datadir à votre copie de la sauvegarde.

Vous pouvez répéter cette opération en copiant la sauvegarde physique sur autant d'instances de développement/test que nécessaire.


Deuxième option: ne pas utiliser INSERT, utilisez LOAD DATA INFILE. Cela peut être d'un ordre de grandeur plus rapide que l'utilisation de INSERT, même avec des instructions préparées et une syntaxe à plusieurs lignes. Troisième option: préparez vos données groupées en tant que fichier CSV, placez-les dans le répertoire de données de votre MySQL, puis créez une table avec ENGINE=CSV pointant vers ce fichier. Voila, vous avez un tableau plein de données. Ensuite, utilisez ALTER TABLE ENGINE=InnoDB et convertissez-le en une véritable table interne.

Questions connexes