Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从CSV raw更快地插入SQLite?_Java_Android_Sqlite_Csv - Fatal编程技术网

Java 从CSV raw更快地插入SQLite?

Java 从CSV raw更快地插入SQLite?,java,android,sqlite,csv,Java,Android,Sqlite,Csv,CSV原始文件大小为11.6 MB 下面是我使用apachecsvreader和SQLCipher所做的代码 下面是从原始数据读取字符串的函数 private String readRawText(int rawId) { InputStream inputStream = cxt.getResources().openRawResource(rawId); InputStreamReader inputreader = new InputStreamReader

CSV原始文件大小为11.6 MB

下面是我使用apachecsvreader和SQLCipher所做的代码

下面是从原始数据读取字符串的函数

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();
    }
以下是从readRawTextint rawId读取的字符串中插入数据的函数:


这需要几分钟。如何加快插入速度?是什么让它变慢的?为什么要慢下来

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

首先将加载的所有数据读入字符串 第二个读取字符串将其逐行拆分,然后插入数据 这个过程需要时间。所以,您可以将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文件读取为一条记录,并将其直接插入数据库。此过程节省了处理时间、内存使用

解决方案代码:

 // 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;
  }

首先,您应该按照@Anil的建议交错读/写过程。从性能和内存的角度来看,没有中间结构都会有所帮助

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

for (record : records)
{
    begin_transaction();
    insert();
    commit_transaction();
}
在我们的例子中,它应该快得多,如果您声明一个显式事务,然后在处理完所有记录后完成它,至少会有3倍的改进

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

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

首先,您应该按照@Anil的建议交错读/写过程。从性能和内存的角度来看,没有中间结构都会有所帮助

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

for (record : records)
{
    begin_transaction();
    insert();
    commit_transaction();
}
在我们的例子中,它应该快得多,如果您声明一个显式事务,然后在处理完所有记录后完成它,至少会有3倍的改进

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

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

您的csv是逗号分隔的文件???您的csv是逗号分隔的文件???如果您的文件分隔符不是逗号,则只更改csv文件使用分隔符的StringTokenizer第二个参数。如果您的文件分隔符不是逗号,然后使用csv文件使用分隔符仅更改StringTokenizer second参数。这将我的处理时间从每10k行数据1分钟缩短为每10k行数据3-5秒,而且它们是相当大的行+1对于经得起时间双关语测试的解决方案:这将我的处理时间从每10k行数据1分钟缩短到每10k行数据3-5秒,而且它们是相当大的一行+1对于经得起时间双关测试的解决方案: