2009-09-02 10 views
2

J'essaie d'insérer environ 500 millions de lignes de données de déchets dans une base de données pour les tests. En ce moment j'ai un script PHP en boucle à travers quelques SELECT/INSERT déclarations à l'intérieur d'un TRANSACTION - clairement ce n'est pas la meilleure solution. Les tables sont InnoDB (verrouillage de ligne).Fourchette MySQL INSERT INTO (InnoDB)

Je me demande si je bifurque (proprement) le processus, cela accélérera-t-il le processus INSERT? Au rythme où ça va, il faudra 140 heures pour terminer. Je suis préoccupé par deux choses:

  1. Si INSERT déclarations doivent acquérir un verrou d'écriture, puis va le rendre inutile bifurquer, car plusieurs processus ne peuvent pas écrire à la même table en même temps? J'utilise SELECT...LAST_INSERT_ID() (dans TRANSACTION). Cette logique se rompra-t-elle lorsque plusieurs processus seront intégrés dans la base de données? Je pourrais créer une nouvelle connexion de base de données pour chaque fork, donc j'espère que cela éviterait le problème.

  2. Combien de processus devrais-je utiliser? Les requêtes elles-mêmes sont simples, et j'ai une boîte de dev standard dual-core avec 2 Go de RAM. J'ai installé mon InnoDB pour utiliser 8 threads (innodb_thread_concurrency=8), mais je ne suis pas sûr si je devrais utiliser 8 processus ou si c'est même une façon correcte de penser à la correspondance.

Merci pour votre aide!

Répondre

4

1) oui, il y aura un conflit de verrouillage, mais innodb est conçu pour gérer plusieurs threads essayant d'insérer. Bien sûr, ils ne seront pas insérés simultanément, mais ils géreront la sérialisation des inserts pour vous. assurez-vous de fermer vos transactions et de le faire le plus rapidement possible. Cela vous permettra d'obtenir les meilleures performances d'insertion possibles. 2) non, cette logique ne se casse pas si vous avez 1 connexion par thread, car last_insert_id() est spécifique à la connexion. 3) c'est l'une de ces choses que vous avez juste besoin de comparer pour comprendre. En fait, je voudrais faire le programme d'auto-ajustement. exécuter 100 insertions avec 8 threads et enregistrer les temps d'exécution. puis réessayez avec la moitié et le double. celui qui est le plus rapide, puis comparez plus de valeurs de nombre de threads autour de ce nombre. En général, vous devriez toujours aller de l'avant et comparer ce genre de choses pour voir ce qui est le plus rapide. dans le temps qu'il vous faut pour y penser et l'écrire, vous pourriez probablement déjà avoir des chiffres préliminaires.

+0

Merci pour la réponse détaillée! Content de savoir qu'il n'y a pas beaucoup de raisons de s'inquiéter. – ash

7

La documentation MySQL a a discussion sur l'insertion efficace d'un grand nombre d'enregistrements. Il semble que le gagnant clair est l'utilisation de la commande LOAD DATA INFILE, suivie par des insertions qui insèrent plusieurs listes de valeurs.

+0

Merci pour cette astuce! 20 fois plus rapide, excellent. – ash