从CSV raw插入SQLite的更快捷方式?

时间:2014-07-10 01:36:13

标签: java android sqlite csv

CSV原始文件大小为11.6 MB。

以下是我使用Apache CSVReader& amp; SQLCipher。

这是从raw读取字符串的函数。

private String readRawText(int rawId) {
        InputStream inputStream = cxt.getResources().openRawResource(rawId);
        InputStreamReader inputreader = new InputStreamReader(inputStream);
        BufferedReader bufferedreader = new BufferedReader(inputreader);
        String line;
        StringBuilder stringBuilder = new StringBuilder();
        try {
            while ((line = bufferedreader.readLine()) != null) {
                stringBuilder.append(line);
                stringBuilder.append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return stringBuilder.toString();
    }

以下是从readRawText(int rawId)

读取的字符串中插入数据的功能
public void insertDefaultBible() {

        StringReader str = new StringReader(readRawText(R.raw.kjv));

        SQLiteDatabase.loadLibs(cxt);
        File databaseFile = new File(Values.database.file);
        SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
                databaseFile, "test123", null);

        Iterable<CSVRecord> records = null;
        try {
            records = CSVFormat.EXCEL.parse(str);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        for (CSVRecord record : records) {
            ContentValues content = new ContentValues();
            content.put("scripture_code", record.get(1));
            content.put("chapter_number", record.get(2));
            content.put("verse_number", record.get(3));
            content.put("content", record.get(4));
            database.insert("kjv", null, content);
        }

    }

需要几分钟。如何才能更快地插入?是什么让它变慢?为什么要慢呢?

2 个答案:

答案 0 :(得分:4)

首先,您应该像@Anil建议的那样交错读/写过程。没有中间结构将有助于从性能和内存的角度来看。

然而,您应该做的另一个重要优化是在单个数据库事务中包含所有插入。 SQLite有implicit transactions,这意味着像这样的循环正在做类似的事情:

for (record : records)
{
    begin_transaction();
    insert();
    commit_transaction();
}

如果您声明一个显式事务,然后在处理完所有记录后完成它,它应该快得多(在我们的例子中,至少提高3倍)。

database.beginTransaction();
try
{
    for (record : records)
        database.insert(...);

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

答案 1 :(得分:0)

你正在使用两种单独的方法

  1. 首先将所有数据加载到String
  2. 第二次读取字符串逐行拆分然后插入数据
  3. 这个过程需要时间。因此,您可以读取csv文件中的一条记录并将其直接插入数据库。此过程可节省处理时间和内存使用量。

    解决方案代码:

     // This method read and writes csv data in one step.
    private boolean readRawTextAndInsert(int rawId) {
          InputStream inputStream = cxt.getResources().openRawResource(rawId);
        InputStreamReader inputreader = new InputStreamReader(inputStream);
        BufferedReader bufferedreader = new BufferedReader(inputreader);
        String line;
        StringTokenizer st = null;
        StringBuilder stringBuilder = new StringBuilder();
        try {
          SQLiteDatabase.loadLibs(cxt);
          File databaseFile = new File(Values.database.file);
          SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
          databaseFile, "test123", null);
    
    
            while ((line = bufferedreader.readLine()) != null) {
                 st = new StringTokenizer(line, ",");
              ContentValues content = new ContentValues();
                content.put("scripture_code", st.nextToken());
                content.put("chapter_number", st.nextToken());
                content.put("verse_number", st.nextToken());
                content.put("content", st.nextToken());
                database.insert("kjv", null, content);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return true;
      }