Fastest way to load data from text file then store it into database

旧时模样 提交于 2019-12-03 21:55:13

The big time killer here will be the sheer number of database connections you are using - try building an in-memory list of commands (which will take almost no time per object compared with reading the data from the file), and once you've built your list, execute them all over a single connection. It takes time to open each connection and you're doing that far more times than needed. Edit - actually noticed you are opening/closing 2 connections per line per file!


Currently (pseudo code for clarity):

For each file (x6)

   Load file from stream

   For each line in file (x12k)

     Read data from line

     Open database connection (happens 72k times)
     Check whether table exists
     Close connection

     Open connection (x72k)
     Try to insert record
     If inserting fails, update existing record
     Close connection

     Next line

   Close filestream

Next file

Suggestion: (and strongly suggest you think about the implications of adding tables dynamically, it's not normally a good solution, but if it's imposed on you maybe you have no choice)

Create an in-memory list of commands 
  (or list of custom objects with property for each command type, create 
  table,insert,update)    

For each file (x6)

   Load file from stream

   For each line in file (x12k)

      Read data from line (all happens 72k times, but no external connections per line)

      Write your create table command
      Write your insert command
      Write your update command
      Add to relevent command lists

   Next Line

   Close filestream

Next File

Open database connection (x1)

For each command in your list
   Apply suitable logic as to whether command needs to execute
   Execute command if applicable
Next command

Close database connection

Why don't you try creating and using an SSIS package? It's very good at this sort of thing, has excellent tooling and quite simple to use from code

http://msdn.microsoft.com/en-us/library/ms141026.aspx

http://blogs.msdn.com/b/michen/archive/2007/03/22/running-ssis-package-programmatically.aspx

You can use a query to insert unmatched records using the Jet driver for text.

SELECT a.* INTO NewTable FROM 
(SELECT * From [Text;DSN=Import Link Specification;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=850;DATABASE=C:\Docs].[Import.txt]) As A
LEFT JOIN OldTable ON a.Key=OldTable.Key
WHERE a.Key Is Null

EDIT

I wonder why you do not have a main table containing all plants and locations. You could then insert all the files into a temp table and either append or update from temp accordingly.

foreach (FileInfo fri in fiarr)
    {
    string s = "[Text;DSN=Test Spec;"
         + "FMT=Fixed;HDR=Yes;IMEX=2;CharacterSet=850;DATABASE=" 
         + fri.DirectoryName + "].["
         + fri.Name + "]";

    query = "INSERT INTO Temp SELECT * FROM " + s;

    cmd.ExecuteNonQuery();
    }

You seem to be using a fixed length format, so DSN=Test Spec is an Access specification create by exporting the file in fixed-width format and then saving the specification using the Advanced button.

One problem here might be that you are inserting each record line-by-line with SINGLE SQL EXECUTE statements.

Another solution would be:

  1. Read the text file into a string buffer (20.000 lines)
  2. Create a DataTable object
  3. In a loop, insert every line into the DataTable object.
  4. Finally, with a DataAdapter, write the DataTable back into the database.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!