Java 从CSV raw更快地插入SQLite?
CSV原始文件大小为11.6 MB 下面是我使用apachecsvreader和SQLCipher所做的代码 下面是从原始数据读取字符串的函数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
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对于经得起时间双关测试的解决方案: