Needing to store about 20,000 rows of information locally in SQLite Database. There are only two columns containing short text strings, so the actual amount of data is small, but I am struggling to get the rows inserted in under 3-5 minutes on the device. I’ve tried just straight up looping through the dataset and calling a simple WritableDatabase.Insert, but that took a long time. So I did some research and was led to the InsertHelper class where the author sites processing rows at about 900 rows/second (which should put me at 20-30 seconds). I still can’t get the data to process any faster than 3-5 minutes. What am I missing? Does performance vary by device? Using ZTE Optik Android 3.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);
}
}
Wrap the entire insert loop in a transaction. This will speed things up by an order of magnitude.