Android Sqlite 性能

标签 android android-asynctask android-sqlite

我一直在做一些实验来测量 sqlite 在 android 上的性能。我对结果有点失望。我所做的是向表中插入 10.000 个查询,花费了 130-140 秒 但在这些条件下

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

2.插入的数据(或类)有3个字符串和一个 float (对于sqlite是真实的)

3. 插入事件在异步任务中完成。

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

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

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

6.此任务在 Activity 的 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;
}

最佳答案

使用SQLite事务来加速

使用 BEGIN TRANSACTIONEND TRANSACTION 进行 SQLite 优化

默认情况下,每个 SQL 语句都由 SQLite 运行时包含在一个新的事务 block 中。因此,当您执行诸如 INSERT 之类的基本数据库操作时,将创建一个事务 block 并将其包裹起来。

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

  1. Android SQLite database: slow insertion

  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

关于Android Sqlite 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28188164/

相关文章:

android - 如何使用 res 文件夹的 drawable-hdpi、drawable-mdpi、drawable-ldpi 中的图像?

android - 内存不足位图解码文件 - Android

java - 使用 WHERE 子句更新 JOIN 另一个表

java - 我到底在哪里/如何在 Android studio 中创建对象/类?

android - 如何检测Android手机中的SIM卡变化?

android - 几次运行后,AsyncTask 在 onPreExecute 后停止

android - java.lang.InternalError 线程在运行时关闭期间启动

java - AsyncTask 在第一行之后崩溃?

android - ListView 中的分页

android - Gettine 异常 : java. lang.IllegalStateException:数据库未打开