Reputation: 12656
I'm getting poor performance and possibly strange behavior with a simple SELECT query in Sqlite & Android. SqliteDatabase.query()
executes my query in only 1 ms, but fetching the results with Cursor.get*()
takes over 150 ms to return only 8 rows!
I am trying to find all the rows in the table english
where the column word
starts with "prefix" (an arbitrary string), sort the results by the row
column, and return only the first 8 results.
Here is my code:
String columns[] = {"word", "rank"};
Cursor cursor = mDB.query("english", columns, "word LIKE '" + prefix + "%'", null, null, null, "rank,word", "8");
// It takes only 1 ms to get here
String word = "";
int rank = 0;
if (cursor.moveToFirst()){
do {
word = cursor.getString(0);
rank = cursor.getInt(1);
}
while(cursor.moveToNext());
}
cursor.close();
// It takes over 150 ms to get here!
The table definition for english
is:
CREATE TABLE en (_id INTEGER PRIMARY KEY, word TEXT, rank INTEGER)
It contains about 65,000 entries. It also also indexes on word
and rank
, with a third index for both (I was getting desperate!):
CREATE INDEX "rank" ON "en" ("rank" ASC)
CREATE INDEX "word" ON "en" ("word" ASC)
CREATE INDEX "word_rank" ON "en" ("word" ASC, "rank" ASC)
Thanks in advance!
Upvotes: 1
Views: 4919
Reputation: 2322
The query method doesn't actually retrieve all the data, the cursor retrieves it as it moves through the rows. So it makes sense that the Cursor.move*() methods are slower then the query.
This 'lazy-loading' concept helps save memory as only the relevant data is retrieved as it's needed.
As for performance, you really aren't doing anything wrong. Are you trying this on the emulator? Perhaps try it on an actual device and test the performance.
Upvotes: 2