2012-07-16 8 views
3

SQLite 데이터베이스에 약 20,000 행의 정보를 로컬로 저장해야합니다. 짧은 텍스트 문자열을 포함하는 두 개의 열만 있으므로 데이터의 실제 양은 적지 만 장치에서 3-5 분 내에 행을 삽입하는 데 어려움을 겪고 있습니다. 나는 데이터 세트를 반복하면서 간단한 WritableDatabase.Insert를 호출 해 보았지만 오랜 시간이 걸렸다. 그래서 나는 약간의 연구를했고 저자 사이트가 약 900 행/초 (20-30 초에 나를 두어야한다)에서 행을 처리하는 the InsertHelper class으로 이끈다. 나는 여전히 3-5 분보다 빨리 처리 할 수있는 데이터를 얻을 수 없다. 내가 뭘 놓치고 있니? 성능은 기기마다 다릅니 까? ZTE Optik 안 드 로이드 사용 3.2.1.Android SQLite 행 수가 많음

public class SqLiteHelper : SQLiteOpenHelper 
{ 
    private const string DATABASE_NAME = "NAME"; 
    private const int DATABASE_VERSION = 1; 
    private readonly Context _context; 

    public SqLiteHelper(Context context) 
     : base(context, DATABASE_NAME, null, DATABASE_VERSION) 
    { 
     _context = context; 
    } 

    public override void OnCreate(SQLiteDatabase db) 
    { 
     try 
     { 
      db.ExecSQL("Create Table Inventory (ItemNumber Text Primary Key Not Null, ItemDescription Text);"); 
     } 
     catch (SQLiteException ex) 
     { 
      Toast.MakeText(_context, ex.Message, ToastLength.Long).Show(); 
     } 
    } 

    public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
    } 
} 

class InventoryRepository : AsyncTask 
{ 
    private SqLiteHelper Helper { get; set; } 
    private Context Context { get; set; } 

    public InventoryRepository(SqLiteHelper helper, Context context) 
    { 
     Helper = helper; 
     Context = context; 
    } 

    protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] @params) 
    { 
     WS ws = new WS(); 
     DataTable parts = ws.GetInventory(); //Web service getting inventory items from Server 

     Helper.WritableDatabase.Delete("Inventory", null, null); 

     DatabaseUtils.InsertHelper ih = new DatabaseUtils.InsertHelper(Helper.WritableDatabase, "Inventory"); 

     Helper.WritableDatabase.SetLockingEnabled(false); 

     int partColumn = ih.GetColumnIndex("ItemNumber"); 
     int partDescColumn = ih.GetColumnIndex("ItemDescription"); 

     Helper.WritableDatabase.BeginTransaction(); 

     try 
     { 

      foreach (DataRow part in parts.Rows) 
      { 
       try 
       { 
        ih.PrepareForInsert(); 

        ih.Bind(partColumn, part[0].ToString().Replace("'", "''")); 
        ih.Bind(partDescColumn, part[1].ToString().Replace("'", "''")); 

        ih.Execute(); 
       } 
       catch (SQLiteException ex) 
       { 
        if (ex.Message.Contains("constraint")) 
         continue; 
        throw; 
       } 
       catch (NullReferenceException e) 
       { 
        continue; 
       } 
      } 
      Helper.WritableDatabase.SetTransactionSuccessful(); 

     } 
     finally 
     { 
      Helper.WritableDatabase.EndTransaction(); 
      Helper.WritableDatabase.SetLockingEnabled(true); 
      ih.Close(); 
     } 

     return "Done"; 
    } 

    protected override void OnPostExecute(Java.Lang.Object result) 
    { 
     PreferenceManager.GetDefaultSharedPreferences(Context).Edit().PutString("LastInventoryUpdate", DateTime.Today.ToShortDateString()).Commit(); 
     Intent intent = new Intent(Context, typeof(Login)); 
     intent.AddFlags(ActivityFlags.NewTask); 
     Context.StartActivity(intent); 
    } 
} 

답변

5

전체 삽입 루프를 트랜잭션으로 래핑하십시오. 이렇게하면 일이 빠르게 진행됩니다.

db.beginTransaction(); 
try { 
    // your insertion loop goes here 
    db.setTransactionSuccessful(); 
} finally { 
    db.endTransaction(); 
} 
+1

22.2 초! 당신은 생명의 은인입니다! – jmease

+0

sqllite 데이터베이스에서 레코드를 가져올 때 가능합니까? 테이블에 10000 개 이상의 레코드가 있습니다. 시간이 많이 걸립니다. 미리 감사드립니다. –

+0

정말 고마워요. – jyomin

관련 문제