Meilleures pratiques pour l'importation de gros fichiers CSV

mon entreprise reçoit un ensemble de fichiers CSV pleins d'informations de compte bancaire chaque mois que je dois importer dans une base de données. Certains de ces fichiers peuvent être assez grande. Par exemple, on a environ 33 Mo et environ 65 000 lignes.

en ce moment j'ai une application symfony/Doctrine (PHP) qui lit ces fichiers CSV et les importe dans une base de données. Ma base de données a environ 35 tables différentes et sur le processus d'importation, je prends ces lignes, les divise en leurs objets constitutifs et les insère dans la base de données. Tout fonctionne à merveille, sauf que c'est lent (chaque ligne prend environ un quart de seconde) et il utilise beaucoup de mémoire.

l'utilisation de la mémoire est si mauvaise que je dois séparer mes fichiers CSV. Un fichier de 20 000 lignes arrive à peine. Quand c'est presque la fin, je suis à 95% d'utilisation de la mémoire. Importer ce fichier de 65 000 lignes n'est tout simplement pas possible.

j'ai trouvé symfony être un cadre exceptionnel pour les applications de construction et je ne le ferais normalement pas pensez à utiliser autre chose, mais dans ce cas, je suis prêt à jeter toutes mes idées préconçues par la fenêtre au nom de la performance. Je ne suis pas engagé dans un langage spécifique, un SGBD, ou quoi que ce soit d'autre.

Stack Overflow n'aime pas les questions subjectives donc je vais essayer de rendre cela aussi peu subjectif que possible: pour ceux d'entre vous n'ont pas seulement une opinion mais expérience de l'importation de gros fichiers CSV, quels outils/pratiques avez-vous utilisé dans le passé que ont été couronnés de succès?

par exemple, utilisez-vous simplement L'ORM/OOP de Django et vous n'avez eu aucun problème? Ou est-ce que vous lisez tout le fichier CSV dans la mémoire et préparez quelques humongous INSERT états?

<!-Encore une fois, je ne veux pas seulement une opinion, mais quelque chose qui a vraiment fonctionné pour vous dans le passé.

Edit: Je ne me contente pas d'importer un tableur CSV à 85 colonnes dans une table de base de données à 85 colonnes. Je normalise les données et je les mets dans des douzaines de les différentes tables. Pour cette raison, je ne peux pas utiliser LOAD DATA INFILE (J'utilise MySQL) ou toute autre fonctionnalité de SGBD qui se lit dans les fichiers CSV.

<!-Aussi, Je ne peux pas utiliser de solutions spécifiques à Microsoft.

22
demandé sur Jason Swett 2010-11-12 19:01:44

10 réponses

j'ai eu ce même problème il y a environ 2 semaines. J'ai écrit quelques .net à faire ligne par ligne inserts et par mes calculs avec la quantité de données que j'avais, il faudrait environ une semaine pour cela de cette façon.

à la place j'ai utilisé un constructeur de chaînes de caractères pour créer une énorme requête et l'ai envoyée à mon système relationnel en une seule fois. Il est passé d'une semaine à cinq minutes. Maintenant, je ne sais pas quel système relationnel vous utilisez, mais avec d'énormes requêtes, vous aurez probablement à modifier votre max_allowed_packet param ou similaire.

10
répondu kmarks2 2010-11-12 16:22:51

Pardonnez-moi si Je ne suis pas exactement comprendre votre problème correctement, mais il semble que vous essayez juste d'obtenir une grande quantité de données CSV dans une base de données SQL. Y a-t-il une raison pour laquelle vous souhaitez utiliser une application web ou un autre code pour traiter les données CSV dans INSERT statements? J'ai réussi à importer de grandes quantités de données CSV dans SQL Server Express (version gratuite) en utilisant SQL Server Management Studio et en utilisant des instructions D'insertion en vrac. Un simple encart en vrac ressemblerait à ceci:

BULK INSERT [Company].[Transactions]
    FROM "C:\Bank Files\TransactionLog.csv"
    WITH
    (
        FIELDTERMINATOR = '|',
        ROWTERMINATOR = '\n',
        MAXERRORS = 0,
        DATAFILETYPE = 'widechar',
        KEEPIDENTITY
    )
GO
17
répondu Lucifer Sam 2010-11-12 16:11:57

d'Abord: 33MB est