2012-05-27 6 views
1

현재 구문 분석하고 데이터를 Android 데이터베이스에 삽입하려고하는 CSV 파일이 있습니다. 내가 가지고있는 문제는 모든 데이터를 삽입하는 데 너무 오래 걸리고 있다는 것입니다. 데이터 양은 많지만 20 분 정도가 지나면 안됩니다.Android - 데이터베이스에 데이터 삽입 속도 향상

기본적으로 내 데이터베이스를 만든 다음 구문 분석을 시작합니다. 각 개별 CSV 행을 구문 분석하는 동안 필요한 데이터를 가져 와서 데이터베이스에 삽입합니다. 전체적으로 약 40000 행이 있습니다.

이 프로세스의 속도를 향상시킬 수있는 방법이 있습니까? 배치 삽입을 시도했지만 정말 잘못하지 않는 한 절대로 도움이되지 않습니다.

아래 코드.

감사합니다.

DatabaseHelper (I 각 CSV 행의 데이터 양에 따라 두 INSERT 명령을)

// add zipcode 
    public void add9Zipcode(String zip, String city, String state, String lat, 
      String longi, String decom) { 

     // get db and content values 
     SQLiteDatabase db = this.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 

     db.beginTransaction(); 
     try{ 

      // add the values 
      values.put(KEY_ZIP, zip); 
      values.put(KEY_STATE, state); 
      values.put(KEY_CITY, city); 
      values.put(KEY_LAT, lat); 
      values.put(KEY_LONG, longi); 
      values.put(KEY_DECOM, decom); 

      // execute the statement 
      db.insert(TABLE_NAME, null, values); 

      db.setTransactionSuccessful(); 
     } finally { 
      db.endTransaction(); 
     } 

     db.close(); 

    } 

    public void add12Zipcode(String zip, String city, String state, String lat, 
      String longi, String decom, String tax, String pop, String wages) { 

     // get db and content values 
     SQLiteDatabase db = this.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 

     db.beginTransaction(); 
     try{ 
      // add the values 
      values.put(KEY_ZIP, zip); 
      values.put(KEY_STATE, state); 
      values.put(KEY_CITY, city); 
      values.put(KEY_LAT, lat); 
      values.put(KEY_LONG, longi); 
      values.put(KEY_DECOM, decom); 
      values.put(KEY_TAX, tax); 
      values.put(KEY_POP, pop); 
      values.put(KEY_WAGES, wages); 

      // execute the statement 
      db.insert(TABLE_NAME, null, values); 

      db.setTransactionSuccessful(); 
     } finally{ 
      db.endTransaction(); 
     } 


     db.close(); 
} 

파싱 파일 :

public void parse(ArrayList<String> theArray, DatabaseHandler db) { 

     String[] data = null; 

     // while loop to get split the data into new lines 
     // for loop to split each string in the array list of zipcodes 
     for (int x = 0; x < theArray.size(); x++) { 

      if(x == 10000 || x == 20000 || x == 30000 || x == 40000){ 
       Log.d(TAG, "x is 10k, 20k, 30k, 40k"); 
      } 

      // split string first into an array 
      data = theArray.get(x).split(","); 

      // separate based on the size of the array: 9 or 12 
      if (data.length == 9) { 

       db.add9Zipcode(data[0], data[2], data[3], data[5], data[6], 
         data[8]); 

      } else if (data.length == 12) { 

       db.add12Zipcode(data[0], data[2], data[3], data[5], data[6], 
         data[8], data[9], data[10], data[11]); 

       /* 
       * theZip.zip = data[0]; theZip.city = data[2]; theZip.state = 
       * data[3]; theZip.lat = data[5]; theZip.longi = data[6]; 
       * theZip.decom = data[8]; theZip. = data[9]; theZip.population 
       * = data[10]; theZip.wages = data[11]; 
       */ 

      } 
     } 

답변

3

내가 만든이 응답 참조 이전 : Inserting 1000000 rows in sqlite3 database

즉, InsertHelper과 트랜잭션 당 하나 이상의 삽입을 수행하십시오 - 당신이 무언가를하지 않는 한, 속도 증가가 눈에 띄어 야합니다.

편집 :
한마디로 :

  1. 귀하의 SQLiteOpenHelper이 전체 응용 프로그램에 걸쳐 사용되는 싱글이어야한다.
  2. SQLiteDatabase 인스턴스에서 close()을 호출하면 안됩니다.이 인스턴스는 SQLiteOpenHelper에 캐시되며 닫을 때마다 도우미가 다시 열도록 강요합니다.
  3. 삽입을 일괄 처리하고 addZipCode 메서드 호출 외의 트랜잭션을 시작한 다음 모든 삽입을 완료 한 후에 트랜잭션을 성공으로 표시 한 다음 트랜잭션을 커밋합니다.
  4. InsertHelper을 사용하십시오. 이는 삽입 문을 준비된 문구로 올바르게 형식화하며 재사용이 가능합니다.
  5. 데이터베이스에 대한 동기화 액세스에주의하십시오 (권장하지는 않음) UI 스레드에서 모든 데이터베이스 작업을 수행하려는 경우가 아니면 동시 액세스를 피하기 위해 데이터베이스에 대한 잠금 또는 가드 액세스를 활성화해야합니다.
+0

그래, 내가 뭔가 이상한 짓을했는지 궁금해. 배치 삽입 코드가 이미 내 addZipcode 메소드에 있습니다. 내가 뭐 잘못 했어요? – Splitusa

+1

당신의 예제에서 두개의'addZipCode'는 삽입 당 * 하나의 트랜잭션을 사용합니다 - 어떤 호출도 데이터베이스를 닫습니다 - SQLiteOpenHelper가 각 삽입에 대해 데이터베이스 파일을 다시 강제 실행합니다 (do * not * 그렇게). 일반적으로, 당신은'SQLiteDatabase'를 계속해서 닫아서는 안됩니다. 귀하의 'SQLiteOpenHelper'는 전체 응용 프로그램에 사용되는 싱글 톤이어야하며, 거의 ** 폐쇄 된 경우는 거의 없습니다. – Jens

+0

도움을 주셔서 감사합니다! – Splitusa