Dans les outils que je crée, j’ai régulièrement besoin d’insérer des CSV dans des bases SQL afin de pouvoir en tirer des statistiques ou des rapports automatiques. Si, lorsque les CSV font quelques centaines ou milliers de lignes, le passage par des entités Doctrine2 est possible (avec une mémoire allouée à PHP suffisante), les limites se font rapidement sentir.
Globalement, au-delà de 10 000 lignes, la solution la plus performante reste la génération d’un fichier SQL, qu’on insère ensuite directement en base à l’aide de la commande exec() de PHP.
Pourtant, un problème subsiste : MySQL ne supporte pas nécessairement des grosses requêtes. Autant on peut mettre autant de « VALUES » qu’on le souhaite dans un unique « INSERT », autant la taille maximale de la requête sera bridée par le paramètre max_allowed_packet ! Fixé de base à une valeur comprise en 1Mo et 16Mo en général, il peut être utile de le pousser jusqu’à 128Mo ou plus. Pour ma part je l’ai carrément mis à 500Mo.
La solution la plus simple consiste à modifier le fichier my.ini de votre serveur MySQL de manière à ajouter la ligne suivante :
PS : attention, si les fichiers sont transférés par formulaire, à ne pas oublier d’augmenter également les valeurs des paramètres PHP :