【问题标题】:Reading from SD card and inserting to SQL table is extremely slow从 SD 卡读取并插入 SQL 表非常慢
【发布时间】:2023-04-02 10:01:02
【问题描述】:

我遇到了一个让我发疯的问题,如果你们能提供任何想法,我将不胜感激。我将数据从 CSV 文件(使用 openCSV)导入数据库,之前这个过程在大约 3-5 秒内完成,包括从服务器下载的时间。 CSV 文件有 3035 条记录。我尝试将解析与 CSV 分离并插入到表格中,但无济于事。

虽然听起来很奇怪,但我的应用程序中突然发生了一些变化,而现在这个过程需要更长的时间。

缩小范围后,我发现 SQLite 插入表非常慢。在过去的几个小时里,我一直在恢复旧代码,看看是否有什么变化,但没有运气。

我遇到了一些类似的问题,其答案建议我使用 InsertHelper,我确实这样做了。这对导入时间完全没有影响。目前插入数据需要 60 秒,而过去只需要几秒钟。

public void importFromCSV() 
{
    SQLiteDatabase db = this.getReadableDatabase();
    db.execSQL("DELETE FROM EXAMS");
    File SDCardRoot = Environment.getExternalStorageDirectory();
    File file = new File(SDCardRoot.getAbsolutePath() + "/Finals/Data/timetable.csv");
    CSVReader reader;
    int i = 0;
    try {
        reader = new CSVReader(new FileReader(file));
        String [] nextLine;
        while ((nextLine = reader.readNext()) != null) {                
            this.addExam(new Exam(nextLine[0],
                                  nextLine[1],
                                  nextLine[2],
                                  nextLine[3],
                                  nextLine[4],
                                  nextLine[5],
                                  nextLine[6],
                                  nextLine[7],
                                  nextLine[8],
                                  nextLine[9]));
        }           

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }



}

public void addExam(Exam exam) {
    SQLiteDatabase db = this.getReadableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_SESSION, exam.getSession());
    values.put(KEY_AWARDING_BODY, exam.getAwardingBody());
    values.put(KEY_QUALIFICATION, exam.getQualification());
    values.put(KEY_TITLE, exam.getTitle());
    values.put(KEY_EXAM_CODE, exam.getExamCode());
    values.put(KEY_DURATION, exam.getDuration());
    values.put(KEY_DATE, exam.getDate());
    values.put(KEY_START_TIME, exam.getStartTime());
    values.put(KEY_EXAM_NOTE, exam.getExamNote());
    values.put(KEY_MY_NOTES, exam.getMyNotes()); 
    db.insert(TABLE_NAME, null, values);

}

【问题讨论】:

  • 你在设备上测试它吗?你试过另一个吗?您发布的代码是关于读取文件,而不是插入到 SQL。也许发布插入片段会更好?我认为这可能与从 SD 读取有关。如果 SD 卡上的空间不足,SD 卡就会变慢
  • 您是否对此进行了分析而不是猜测?您应该使用 systrace 工具并尝试找出瓶颈所在。
  • 我在 One X 和 HD2 上都试过了,同样的情况也出现在模拟器上。 addExam 方法将其插入到数据库中。因此,当它从 CSV 文件中读取时,它会立即输入。

标签: android performance sqlite insert opencsv


【解决方案1】:

您的插入可能会很慢,因为您必须为每个插入设置参考。 Jeff Sharkey 实际上刚刚在 Google IO 1012 上详细讨论了这个问题。https://developers.google.com/events/io/sessions/gooio2012/103/ 基本上,您应该将所有内容都包含在尽可能少的事务中。

try{
  db.beginTransaction();
  for each record in the list {
     do_some_processing();
     if (line represent a valid  entry) {
        db.insert(SOME_TABLE, null, SOME_VALUE);
     }
     some_other_processing();
  }
  db.setTransactionSuccessful();
} catch (SQLException e) {
} finally {
  db.endTranscation();
}

【讨论】:

  • 是的!这行得通。它在 2 秒内完成工作,而不是 60 秒以上。谢谢,不胜感激。
  • 没有。问题。感谢您的支持并接受。让我帮助更多:)
猜你喜欢
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
相关资源
最近更新 更多