【问题标题】:Android - Speed up inserting data in databaseAndroid - 加快在数据库中插入数据
【发布时间】:2012-05-27 08:12:59
【问题描述】:

我目前有一个 CSV 文件,我正在解析并尝试将数据插入到 android 数据库中。我遇到的问题是插入所有数据花费的时间太长。这是一个很好的数据量,但我觉得它不应该需要 20 分钟左右才能完成。

基本上,我创建了我的数据库,然后开始解析。在解析每个单独的 CSV 行时,我抓取所需的数据并将其插入数据库。总共有大约 40000 行。

有什么方法可以加快这个过程吗?我尝试过批量插入,但它从来没有真正帮助过(除非我做错了)。

下面的代码。

谢谢。

DatabaseHelper(根据每个 csv 行中的数据量,我有两个插入命令):

// add zipcode
    public void add9Zipcode(String zip, String city, String state, String lat,
            String longi, String decom) {

        // get db and content values
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        db.beginTransaction();
        try{

            // add the values
            values.put(KEY_ZIP, zip);
            values.put(KEY_STATE, state);
            values.put(KEY_CITY, city);
            values.put(KEY_LAT, lat);
            values.put(KEY_LONG, longi);
            values.put(KEY_DECOM, decom);

            // execute the statement
            db.insert(TABLE_NAME, null, values);

            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }

        db.close();

    }

    public void add12Zipcode(String zip, String city, String state, String lat,
            String longi, String decom, String tax, String pop, String wages) {

        // get db and content values
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        db.beginTransaction();
        try{
            // add the values
            values.put(KEY_ZIP, zip);
            values.put(KEY_STATE, state);
            values.put(KEY_CITY, city);
            values.put(KEY_LAT, lat);
            values.put(KEY_LONG, longi);
            values.put(KEY_DECOM, decom);
            values.put(KEY_TAX, tax);
            values.put(KEY_POP, pop);
            values.put(KEY_WAGES, wages);

            // execute the statement
            db.insert(TABLE_NAME, null, values);

            db.setTransactionSuccessful();
        } finally{
            db.endTransaction();  
        }


        db.close();
}

解析文件:

public void parse(ArrayList<String> theArray, DatabaseHandler db) {

        String[] data = null;

        // while loop to get split the data into new lines
        // for loop to split each string in the array list of zipcodes
        for (int x = 0; x < theArray.size(); x++) {

            if(x == 10000 || x == 20000 || x == 30000 || x == 40000){
                Log.d(TAG, "x is 10k, 20k, 30k, 40k");
            }

            // split string first into an array
            data = theArray.get(x).split(",");

            // separate based on the size of the array: 9 or 12
            if (data.length == 9) {

                db.add9Zipcode(data[0], data[2], data[3], data[5], data[6],
                        data[8]);

            } else if (data.length == 12) {

                db.add12Zipcode(data[0], data[2], data[3], data[5], data[6],
                        data[8], data[9], data[10], data[11]);

                /*
                 * theZip.zip = data[0]; theZip.city = data[2]; theZip.state =
                 * data[3]; theZip.lat = data[5]; theZip.longi = data[6];
                 * theZip.decom = data[8]; theZip. = data[9]; theZip.population
                 * = data[10]; theZip.wages = data[11];
                 */

            }
        }

【问题讨论】:

    标签: android database sqlite insert


    【解决方案1】:

    参考我之前的回答:Inserting 1000000 rows in sqlite3 database

    简而言之,使用 InsertHelper 并在每个事务中执行多次插入 - 除非您做了一些不可靠的事情,否则速度应该会明显提高。

    编辑:
    简而言之:

    1. 您的 SQLiteOpenHelper 应该是在整个应用程序中使用的单例。
    2. 不要在 SQLiteDatabase 实例上到处调用 close() - 它缓存在 SQLiteOpenHelper 中,每次关闭时都会强制帮助程序重新打开它。
    3. 批量插入,在调用 addZipCode 方法之外启动事务,并在完成所有插入后将其标记为成功 - 然后提交事务。
    4. 使用InsertHelper - 它会将插入正确格式化为准备好的语句,并且很好且可重复使用。
    5. 注意同步访问数据库 - 除非您打算在 UI 线程上完成所有数据库工作(不建议这样做) - 您需要启用锁定或保护对数据库的访问以避免并发访问。

    【讨论】:

    • 是的,我想知道我是否确实做了一些奇怪的事情。批量插入代码已经在我的 addZipcode 方法中。我做错了吗?
    • 您的示例中的两个 addZipCode 每次插入使用 一个 事务(从来没有批处理)-它们还会为每次调用关闭数据库-这会强制您的 SQLiteOpenHelper为每个插入重新打开数据库文件(不要那样做)。通常,您不应该一遍又一遍地关闭SQLiteDatabase。您的 SQLiteOpenHelper 应该是在整个应用程序中使用的单例 - 并且很少曾经关闭。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多