Android Java Эффективный запрос SQLite с прерыванием

У меня есть таблица с> 200000 строк (и может быть несколько миллионов).

Иногда запросы могут занять несколько минут, чтобы вернуть результат.

Мне нужно предложить конечному пользователю возможность прервать запрос и уточнить его.

Для этого мне нужно реализовать запрос, который можно отменить или прервать.

Есть ли лучшая практика для этого?

Решение, которое я придумал, состоит в том, чтобы выполнить серию небольших запросов, используя LIMIT и OFFSET, проверяя прерывание между ними.

Меня беспокоит то, что многократное использование LIMIT и OFFSET приведет к поиску одних и тех же строк данных снова и снова, что приведет к гораздо более медленному запросу. Или SQLite распознает, что может начать следующий запрос с номера строки, на котором остановился предыдущий идентичный поиск?

public class InterruptableQuery {

    public interface QueryResult {
        void queryResult(boolean interrupted, List<MyData> results);
    }
    private QueryResult queryCallBack;

    private volatile boolean _interrupted = false;
    private volatile boolean _cancelled = false;
    private SQLiteDatabase db;

    public InterruptableQuery(SQLiteDatabase db, QueryResult qr) {
        this.db = db;
        queryCallBack = qr;
    }

    public void interruptQuery() { _interrupted = true; }
    public void cancelQuery() { _cancelled = true; }

    public void search(final String query) {
        Thread searchThread = new Thread() {
            @Override
            public void run() {
                boolean done = false;
                int OFFSET = 100;
                int offset = 0;
                List<MyData> resultsList = new ArrayList<>();
                while (!done && !_cancelled && !_interrupted) {
                    Cursor cursor = db.rawQuery(query + " LIMIT " + OFFSET + " OFFSET " + offset, null);
                    done = (cursor == null) || (cursor.getCount() < OFFSET);
                    if (cursor != null) {
                        if (cursor.moveToFirst()) {
                            do {
                                resultsList.add(new MyData(cursor));
                            } while (cursor.moveToNext());
                        }
                        cursor.close();
                    }
                    offset += OFFSET;
                }
                if (!_cancelled)
                    queryCallBack.queryResult(_interrupted, resultsList);
            }
        };
        searchThread.start();
    }
}

0 ответов

Другие вопросы по тегам