具有中断的Android Java高效SQLite查询

时间:2017-01-23 17:29:50

标签: java android sqlite android-sqlite suspend

我有一张带有>的表格200,000行(可能是几百万行)。

有时查询可能需要几分钟才能返回结果。

我需要为最终用户提供中止查询并对其进行优化的能力。

为此,我需要实现一个可以取消或中断的查询。

这是最好的做法吗?

我提出的解决方案是使用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 个答案:

没有答案