【问题标题】:Faster way to insert into SQLite from CSV raw? [duplicate]从 CSV raw 插入 SQLite 的更快方法? [复制]
【发布时间】:2014-08-31 05:14:44
【问题描述】:

CSV 原始文件大小为 11.6 MB。

这是我使用 Apache CSVReader 和 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);
        }

    }

这需要几分钟。我怎样才能使它更快地插入?是什么让它变慢?为什么要让它变慢?

【问题讨论】:

  • 你的 csv 是逗号分隔的文件???

标签: java android sqlite csv


【解决方案1】:

你正在使用两种不同的方法

  1. 首先将所有数据加载到一个字符串中
  2. 第二次读取字符串逐行拆分,然后插入数据

这个过程需要时间。因此,您可以读取 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;
  }

【讨论】:

  • 如果你的文件分隔符不是逗号(,),那么只用你的 csv 文件分隔符更改 StringTokenizer 第二个参数。
【解决方案2】:

首先,您应该按照@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();
}

【讨论】:

  • 这将我的处理时间从每 10k 行数据 1 分钟缩短到每 10k 行数据 3-5 秒,而且它们是相当长的行。 +1 表示经得起时间考验的解决方案(双关语):)
猜你喜欢
  • 2012-12-23
  • 1970-01-01
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 2017-03-03
  • 2013-04-11
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多