Barry Fruitman
Barry Fruitman

Reputation: 12656

How do I improve the performance of my SELECT query in Sqlite / Android?

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

Answers (1)

Kane Wallmann
Kane Wallmann

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

Related Questions