2011-03-10 4 views
4

csv 파일에서 sqlite 테이블로 데이터를 가져 오려고했습니다. 테스트 데이터는 약 8MB (50,000 행)이며 약 15 초가 걸립니다. 그러나 생산 데이터는 거의 400Mb이며, 영원히 (적어도 30mins +, 나는 포기했다).Slow Batch/Bulk Insert into SQLite

많은 연구 끝에 단일 트랜잭션에서 삽입 작업을 수행해야한다는 것을 알았습니다 (15 초 수입, 훌륭한 조언을 받았습니다! :)) 그래서 문제는 아닙니다. (AFAIK)

나는 또한 Robert Simpson post 및 그 변형에 따라 "매개 변수가있는 INSERT 문에서 ExecuteNonQuery()"를 사용하고 있습니다. 난 그냥 TextReader.ReadLine()String.Split('\t')을 사용했다

, 그럼 어디 선가 대한 ReadLine() 인해 디스크의 수 읽기에 속도가 느린 것을 읽고, 그래서 한 BufferedStream 읽기에보고하고, this csv reader을 가로 질러왔다. 그러나 성능에서 눈에 띄는 변화는 없습니다.

그래서 삽입 루프의 결함에 대해 즉시 주석을 달았습니다. 즉각적으로 읽음이 발생합니다. 문제가 삽입되는 것입니다. 나는 매개 변수화 된 쿼리 + 단일 트랜잭션을 생성하는 다양한 변형을 시도했지만 거의 동일한 결과를 얻었습니다.

다음은 정규 코드입니다. 미리 감사드립니다, 이것은 나를 미치게합니다! ? 나는 ....

using (TextReader tr = File.OpenText(cFile)) 
{      
    using (SQLiteConnection cnn = new SQLiteConnection(connectionString)) 
    { 
     string line; 
     string insertCommand = "INSERT INTO ImportTable VALUES (@P0,@P1,@P2,@P3,@P4)"; 

     cnn.Open(); 
     SQLiteCommand cmd = new SQLiteCommand("begin", cnn); 
     cmd.ExecuteNonQuery(); 

     cmd.CommandText = insertCommand; 

     while ((line = tr.ReadLine()) != null) 
     { 
      string[] items = line.Split('\t'); 

      cmd.Parameters.AddWithValue("@P0", items[0]); 
      cmd.Parameters.AddWithValue("@P1", items[1]); 
      cmd.Parameters.AddWithValue("@P2", items[2]); 
      cmd.Parameters.AddWithValue("@P3", items[3]); 
      cmd.Parameters.AddWithValue("@P4", items[4]); 
      cmd.ExecuteNonQuery(); 
     } 
     cmd.CommandText = "end"; 
     cmd.ExecuteNonQuery(); 
    }    
} 

업데이트 DataSet에 수입하고 삽입 시도하려고 해요 : 난 그냥 (그냥 하드 코딩 된 값)보다 5 초 매개 변수로 삽입을 사용하여 시도 .. 아직까지 내가 본 기사만큼 빠르지는 않습니다 ...

또한 2G RAM, XP가 포함 된 Core2 Duo (3Ghz)를 실행하고 있습니다.

+0

정말로 'begin'과'end' 명령이 작동합니까? 당신이 그들을 제거하면 실행 시간에 변경 사항을 통지합니까? –

+0

감사합니다. 네, 일하는 것 같아요. 나는 그것들없이 지금 그것을 시도하고 있으며 적어도 10 분 (15 초)이 걸렸다. 나는 또한 transaction = connection.BeginTransaction() /. transaction.commit way (위와 같은 방법으로 정상적인 수행)을 시도했다. – DougF

+0

확인. 그걸 확인하고 싶었을 뿐이에요. 왜냐하면 제가 Transaction이나 TransactionScope를 사용하라고 제안했기 때문에 ...하지만 그건 당신의 문제를 해결하지 못할 것입니다 ... –

답변

1

그래서 나는 문제를 해결했거나 최소한 해결책을 찾았다 고 생각합니다. 내 모든 코드 옵션을 소진했던 이후

, 나는 ... 문제는 데이터베이스 자체 내에서 거짓말 수 결정 (그리고 사람처럼 보이지 않았다 내 코드와 응답/문제가 있었다)

SQLite Manager Firefox Plugin 내에서 데이터베이스와 테이블을 모두 만들었습니다.

그래서 명령 셸과 붐에서 모든 것을 재현했습니다! 내 수입이 몇 초로 떨어졌습니다!

64 비트 정수를 처리 할 수 ​​없다는 문제가 있다는 것을 알고있었습니다 (단, TEXT 데이터 유형 만 사용 했음). 아마도 .NET 버전에 다른 SQLite 엔진을 사용하는 SQLite Manager에 문제가 있습니까? 나는 모른다.

내 다음 단계는 실제로 응용 프로그램 내에서 미리 준비하는 대신 db + 테이블을 만드는 것일 수 있습니다 ...하지만 지금은 성능에 상당히 만족하므로 우선 순위가 아닙니다.