2014-09-04 3 views
2

작은 프로젝트를 만들었습니다. 사용자가 Entity-Framework를 통해 CSV 파일을 SQL로 가져올 수 있습니다. 주요 절차는 다음과 같이보고한다 :CSV를 SQL 서버로 가져 오기 - 성능

using (TextFieldParser tx = new TextFieldParser(file, Encoding.UTF8)) 
     { 
      tx.TextFieldType = FieldType.Delimited; 
      tx.SetDelimiters(";"); 
      tx.ReadLine(); //The First Line are the headers, no need 

      while (!tx.EndOfData) 
      { 
       decimal decTmp; 
       int intTmp; 

       string[] fields = tx.ReadFields(); 

       //Convert every field to the appropriate type, tryparse if nullable 
       ReportInfo("Verarbeite Nummer: " + fields[(int)ConnectionEvaluationFileField.PhoneNumber].Trim()); 

       Verbindunganalyse con = new Verbindunganalyse(); 
       con.Auswertungszeitraum = fields[(int)ConnectionEvaluationFileField.EvaluationTimeSpan].TrimStart('0'); 
       con.Betrag_inkl_MWST_CHF = Decimal.Parse(fields[(int)ConnectionEvaluationFileField.Cost]); 
       if (decimal.TryParse(fields[(int)ConnectionEvaluationFileField.DataInMb], out decTmp)) 
        con.Daten_MB = decTmp; 
       con.Durchwahlnummer = Int64.Parse(fields[(int)ConnectionEvaluationFileField.PhoneNumber]); 
       con.Produkteigenschaft = fields[(int)ConnectionEvaluationFileField.ProductProperty]; 
       if (Int32.TryParse(fields[(int)ConnectionEvaluationFileField.Messages], out intTmp)) 
        con.SMS_MMS_Anzahl = intTmp; 
       con.TelefonieDauer = TimeSpan.Parse(fields[(int)ConnectionEvaluationFileField.CallLength]); 

       con.Untergruppe = fields[(int)ConnectionEvaluationFileField.SubGroup]; 

       if (Int32.TryParse(fields[(int)ConnectionEvaluationFileField.Connections], out intTmp)) 
        con.Verbindungen_Anzahl = intTmp; 

       container.Verbindunganalyse.Add(con); 
      } 
     } 

그것은 독일어,하지만 코드가 매우 분명하다 생각 : 나는 TextFieldParser와 데이터를 읽기, 새로운 실재물을 생성하고 구문 분석/재산에 필드를 확인합니다.

문제점 : 고객이 솔루션을 사용하여 데이터를 가져 오는 데 20-30 초가 필요했던 Access-Solution을 사용했는데 2k 파일에 2-3 분, 5k 데이터 세트가 필요합니다.

https://efbulkinsert.codeplex.com/과 같은 일부 BulkInsert가 발견되었지만 두 파일의 10k 데이터 세트를 함께 사용하고 있습니다.

ReportInfo 등을 제거했지만 빠르게 작동하는 방법을 볼 수 없습니다. 당신은 EF로 그러한 것들을 더 빨리 만들 가능성이 있습니까? 아니면 TextFieldParser가 매우 느리고 거기를 확인해야합니까?

+0

어떤 부분이 느린 지 알고 있습니까? 그것은 텍스트 파일을 통한 루프인가? Entity Framework에 대한 삽입입니까? 후자의 경우 BulkInsert 및 by-passing EntityFramework를 사용하는 것이 좋습니다. –

+0

데이터 집합이 몇 밀리 초보다 오래 필요합니다. 문제는 액세스가 SQL에 대량 삽입 될 수 있다는 것입니다. 탐구는 그걸 싸우는 것입니다. 더 느려질 수는 있지만, 단지 10 배가되지는 않습니다. –

+1

대량 삽입은 SQL Server에서 매우 효율적으로 작동합니다. http://msdn.microsoft.com/en-us/library/ms188365.aspx. –

답변

0

나는 이것이 오래된 게시물이라는 것을 알고 있지만, 나는 이것으로 직접 실험 해왔다. 다음 코드를 사용하여 Entity Framework Seeder NuGet packagebare-metal SQL bulk insert을 모두 시도했습니다.

CREATE TABLE [dbo].[TempTable] (
    [Field] type constraints, 
    etc... 
) 
GO 
BULK INSERT TempTable FROM 'filePath' WITH (
    FIRSTROW = 2, 
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\r\n' 
) 
GO 
INSERT INTO [FinalTable] SELECT [Fields] FROM [TempTable] 
GO 
DROP TABLE [TempTable] 

시드 메서드는 10,000 개의 레코드를 67 초 동안 삽입하고 대량 삽입 메서드는 223ms를 사용합니다. 정말 생각할 필요가 없습니다.