我有一张带有>的表格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();
}
}