3

SQLiteデータベースにローカルに約20,000行の情報を保存する必要があります。短いテキスト文字列を含む列は2つしかないため、実際のデータ量は少ないですが、デバイスに3〜5分以内に行を挿入するのに苦労しています。データセットをループして単純なWritableDatabase.Insertを呼び出してみましたが、時間がかかりました。そこで、私はいくつかの調査を行い、InsertHelperクラスに導かれました。そこでは、作成者が約900行/秒で行を処理します(これにより、20〜30秒かかるはずです)。それでも、3〜5分より速くデータを処理することはできません。私は何が欠けていますか?パフォーマンスはデバイスによって異なりますか?ZTE OptikAndroid3.2.1の使用。

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);
    }
}
4

1 に答える 1

5

挿入ループ全体をトランザクションでラップします。これにより、処理が1桁高速化されます。

db.beginTransaction();
try {
    // your insertion loop goes here
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
于 2012-07-16T15:48:04.950 に答える