Android Sqlite性能

Mer*_*mer 13 android android-asynctask android-sqlite

我一直在做一些实验来测量android上的sqlite性能.我对结果感到失望.我所做的是向表中插入10.000个查询,并且需要130-140秒 才能满足这些条件 ;

1.三星galaxy s3处于省电模式

2.插入的数据(或类)有3个字符串和1个浮点数(对于sqlite是真的)

3.插入事件正在asynctask中完成.

4.在asynctask中,我显示了一个进度对话框,其中包含传递的计时器文本(System.currentTimeMillis - seconds etc blala)

class AddStudentsTask extends AsyncTask<Void,Integer,Void>
{
    ProgressDialog prgDialog;
    int max = 10000;
    Student s;
    long seconds = System.currentTimeMillis();


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        prgDialog = new ProgressDialog(MainActivity.this);
        prgDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        prgDialog.setMessage(seconds+"");
        prgDialog.setMax(max);
        prgDialog.setCancelable(false);
        prgDialog.show();

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate();
        prgDialog.setProgress(values[0]);
        sList.add(s);
        String s = (System.currentTimeMillis()-seconds)/100+"";
        if(s.length()>2)
            s = s.substring(0,s.length()-1) + "." + s.charAt(s.length()-1);
        else if(s.length() == 2)
            s = s.charAt(0) + "." + s.charAt(1);
        prgDialog.setMessage(s + " seconds passed.");

    }

    @Override
    protected Void doInBackground(Void... voids) {

        for(int a = 0;a< max; a++ )
        {
            Random r = new Random();
            s = new Student();

            s.setGpa(r.nextFloat()*4);
            s.setLastName("asdasd");
            s.setFirstName("Oh My God");
            s.setAddress("1sadasd");
            s.setId(sda.insert(s));
            publishProgress(a);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        prgDialog.dismiss();
        sa.notifyDataSetChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)

5.我在helperdb类中使用带有insertOrThrow方法的contentValues. 这是旧的慢速代码

public long insert(Student s)
{
    SQLiteDatabase db = sh.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(StudentHelper.FIRSTNAME,s.getFirstName());
    cv.put(StudentHelper.LASTNAME,s.getLastName());
    cv.put(StudentHelper.ADDRESS,s.getAddress());
    cv.put(StudentHelper.GPA,s.getGpa());
    s.setId(db.insertOrThrow(StudentHelper.TABLE_NAME, null, cv));
    return s.getId();
}
Run Code Online (Sandbox Code Playgroud)

6.此任务在onCreate活动方法中完成.

那我在这里做错了什么或者期待太多呢?这些结果好还是坏?

我该怎么做才能改进我的代码?

编辑

所以我将我的插入代码更改为此,它减少到4.5秒!

public ArrayList<Long> insertMany(ArrayList<Student> stus)
{
    ArrayList<Long> ids = new ArrayList();
    String sql = "INSERT INTO "+StudentHelper.TABLE_NAME+"" +
            "("+StudentHelper.FIRSTNAME+","+StudentHelper.LASTNAME+"," +
            " "+StudentHelper.GPA+") values(?,?,?)";
    SQLiteDatabase db = sh.getWritableDatabase();
    db.beginTransaction();

    for(Student s:stus) {
        SQLiteStatement stmt = db.compileStatement(sql);

        stmt.bindString(1, s.getFirstName());
        stmt.bindString(2, s.getLastName());
        stmt.bindDouble(3, s.getGpa());

        s.setId(stmt.executeInsert());
        ids.add(s.getId());
        stmt.clearBindings();
    }

    db.setTransactionSuccessful();
    db.endTransaction();

    return ids;
}
Run Code Online (Sandbox Code Playgroud)

M D*_*M D 29

使用SQLite transaction用于加快

使用BEGIN TRANSACTIONEND TRANSACTION进行SQLite优化

默认情况下,SQLite运行时将每个SQL语句括在一个新的事务块中.如果您执行基本数据库操作(如INSERT),将创建一个事务块并将其包装.

只有在例程对数据集执行一次数据库操作时,才建议让SQLite运行时为您管理事务.但是,如果您正在进行大量的数据库操作(比如INSERT in for循环),这将变得非常昂贵,因为它需要重新打开,写入和关闭每个语句的日志文件.你可以参考

  1. Android SQLite数据库:插入缓慢

  2. http://www.androidcode.ninja/android-sqlite-transaction-tutorial/

  3. http://www.techrepublic.com/blog/software-engineer/turbocharge-your-sqlite-inserts-on-android/

  4. http://www.android-app-market.com/sqlite-optimization-in-android-programming-sqlite-optimization-in-android-apps.html

  • 谢谢你的答案.它加速了20倍lol.花了7.5秒 (4认同)
  • 我为以后的问题编辑者编辑了我的文章,以便他们可以更改其代码。 (2认同)

van*_*jar 9

您可以像这样在Android中使用SQL 事务.最好以较大的批次向数据库中插入多行,然后对每个插入的行进行单次提交(写入非常慢的SQLlite数据文件).

public void insert(List<Student> students)
{
    SQLiteDatabase db = sh.getWritableDatabase();
    ContentValues cv = new ContentValues();

    db.beginTransaction();

    try {
        for (Student s : students) {
                cv.put(StudentHelper.FIRSTNAME,s.getFirstName());
                cv.put(StudentHelper.LASTNAME,s.getLastName());
                cv.put(StudentHelper.ADDRESS,s.getAddress());
                cv.put(StudentHelper.GPA,s.getGpa());

                db.insertOrThrow(StudentHelper.TABLE_NAME, null, cv)
        }
        setTransactionSuccessful();
    } finally {
         db.endTransaction();
    }
}
Run Code Online (Sandbox Code Playgroud)