Производительность вставки Android SQLite - PullRequest
0 голосов
/ 21 ноября 2018

Возможно, я просто сталкиваюсь с собственными проблемами с производительностью SQLite, но, похоже, существуют значительные накладные расходы, связанные со вставкой в ​​SQLite, даже с использованием обработки транзакций и предварительно скомпилированных операторов.Или, возможно, я использую их неправильно.

У меня есть требование читать файл построчно (через URL) и создавать строки.Механизм является общим, поэтому можно создать любую таблицу (в пределах разумного) и добавить любое количество строк.Я вижу довольно приличную производительность для больших вставок, но с меньшими, кажется, у меня есть минимум + 400 мс.Поскольку у меня может быть более 100 из них для загрузки, эти небольшие накладные расходы приводят к большому времени загрузки.

Например, некоторые моменты времени:

   34 records Test #1  ---->  490 ms
36238 records Test #2  ----> 3021 ms
    4 records Test #3  ---->  520 ms

Вот код (я вырезал всеtry / ловит и другой код, чтобы свести его к фактическому коду вставки):

        InputStream input = new BufferedInputStream(url.openStream());

        // Create the file reader
        BufferedReader  br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
        StringBuffer insertSql = null;

        // Build the SQL to bind
        insertSql = new StringBuffer("INSERT INTO " + fileName + " (");
        String sep = "";
        insertSql.append("[" + getDbColumnNames().replaceAll(" ", "").replaceAll(",", "],[") + "]");
        String[] columns = getDbColumnNames().split(",");
        insertSql.append(") VALUES (");
        for (@SuppressWarnings("unused") String col : columns) {
            insertSql.append(sep.trim() + "?");
            sep = ",";
        }
        insertSql.append(");");
        this.open();
        sqlDB.beginTransaction();
        SQLiteStatement stmt = = sqlDB.compileStatement(insertSql.toString());

        String line = "";
        // Read the file line by line
        while ((line = br.readLine()) != null) {
            String[] tokens = line.split(",");
            // Build the bindings and insert the data
            int bindcnt = 1;
            for (String token : tokens) {
                 stmt.bindString(bindcnt++, token.trim());
            }

            long entryID = stmt.executeInsert();
            if (entryID < 0) {
                success = false;
            }
            stmt.clearBindings();
        }
        sqlDB.setTransactionSuccessful();
        sqlDB.endTransaction();

Я убедился, что накладные расходы буфера чтения не значительны для большинства операций чтения.

...