Android / SQLite - 最快的插入?

时间:2017-05-22 15:22:16

标签: android sqlite csv

长话短说:

我有一个类似8.000条记录(和4个字段)的CSV文件。 我必须下载它并在该过程之后将每个记录插入sqllite表中。

所以我做了一笔交易:

    SQLiteDatabase db = this.getWritableDatabase();
    db.beginTransaction();
    try
    {
        String line;
        int i=0;
        do {
            line = buffreader.readLine();

            i++;
            if(i==1)
                continue; //Header of the CSV

            if(line != null)
            {
                String[] values = line.split(";");
                if(values.length != 4 )
                    continue;

                sql = String.format("INSERT INTO TABLE (FIELD_1, FIELD_2, FIELD_3, FIELD_4) VALUES (%s, %s, %s, %s)",
                        values[0],
                        values[1],
                        values[2],
                        values[3]);
                db.execSQL(sql);
            }
        }
        while (line != null);

        db.setTransactionSuccessful();
    }
    catch (SQLiteException ex)
    {
        Log.d(TAG, "Well.. : " + ex.getMessage());
        throw ex;
    }
    finally
    {
        db.endTransaction();
    }

一切正常,我的手机和其他手机需要8-9秒。 可悲的是,在必须运行此应用的Android设备上(带有双核处理器的白标设备)需要6-7分钟!

当然我的老板对此并不满意,他确实同意在使用四核处理器的“常规”手机上一切都比较快但我们必须让它在这个双核上工作,6-7分钟看起来像是一个问题。关于如何解决它的任何想法?

2 个答案:

答案 0 :(得分:1)

1)分离您的进程(文件读取和数据库插入)。你需要消耗更少的内存。

2)插入多个记录:INSERT INTO ... VALUES (1,2,3,4),(5,6,7,8),(9,10,11,12)。通过这种方式,您可以获得较低的I / O.

3)使用查询参数

答案 1 :(得分:0)

所以,我们还有一些实验。

我删除"拆分CSV部分"。 " record_list"变量是27358记录。 我评论数据库操作'因为建议我尝试确定花费的时间。我添加了两个Date变量,所以我可以看到它真正需要多少。

好吧,使用白标设备填充SQL查询需要159秒。如果我取消注释数据库操作,它需要相同的时间(165秒)。所以问题出在String创建中,我认为它已经在最佳状态下进行了优化..

这是代码

    String[] record_list = Split_CSV(); 

    Date StartDate = new Date();
    //SQLiteDatabase db = this.getWritableDatabase();
    //db.beginTransaction();
    try
    {
        StringBuilder sql = new StringBuilder();

        int i=0;

        for (String line : record_list)
        {
            String[] values = line.split(";");

            if (i==0)
            {
                sql.append("INSERT INTO TABLE (FIELD_1, FIELD_2, FIELD_3, FIELD_4) VALUES ");
            }

            i = i+1;
            sql.append(String.format("(%s,%s,%s,%s), ",
                    values[0],
                    values[1],
                    values[2],
                    values[3]));

            if (i==500)
            {
                i = 0;
                //db.execSQL(sql.substring(0,sql.length()-2));
                sql.setLength(0);
            }
        }

        if (sql.length()!=0) {
            //db.execSQL(sql.substring(0, sql.length() - 2));
            sql.setLength(0);
        }

        //db.setTransactionSuccessful();
    }
    catch (SQLiteException ex)
    {
        Log.d(TAG, "addAnagraficheClienti : " + ex.getMessage());
        throw ex;
    }
    finally
    {
        //db.endTransaction();
    }

    Date EndDate = new Date();

如果有人不知道: " INSERT"每500条记录被拆分以及此评论的原因:

Is it possible to insert multiple rows at a time in an SQLite database?

我正在读那个:

进一步说明,sqlite似乎每个查询只支持最多500个这样的联合选择,所以如果你试图输入的数据多于你需要将它分解为500个元素块