sqlite не использует индекс на Android

Я выполняю следующий запрос к базе данных sqlite на рабочем столе и Android:

SELECT kdtree_nonendpt.verid, minlat, minlon, data
FROM kdtree_nonendpt, kdtree_nonendpt_data
WHERE kdtree_nonendpt.verid IN (SELECT kdtree_nonendpt.verid
                                FROM kdtree_nonendpt
                                WHERE minlat>=? AND maxlat<=? AND minlon>=? AND maxlon<=?
                               ) AND
      kdtree_nonendpt.verid = kdtree_nonendpt_data.verid

Это структура данных

.schema kdtree_nonendpt
CREATE VIRTUAL TABLE kdtree_nonendpt USING rtree(verid UNSIGNED INT PRIMARY KEY,minlat REAL, maxlat REAL, minlon REAL, maxlon REAL); 

.schema kdtree_nonendpt_data
CREATE TABLE kdtree_nonendpt_data(verid UNSIGNED INT PRIMARY KEY,data TEXT);
CREATE INDEX kdtree_nonendpt_data_idx ON kdtree_nonendpt_data(verid);

Это результат EXPLAIN QUERY выше на Android

0 0 1 SCAN TABLE kdtree_nonendpt_data (~31805 rows)
0 1 0 SCAN TABLE kdtree_nonendpt VIRTUAL TABLE INDEX 1: (~0 rows)
0 0 0 EXECUTE LIST SUBQUERY 1
1 0 0 SCAN TABLE kdtree_nonendpt VIRTUAL TABLE INDEX 2:DaBbDcBd (~0 rows)

И это результат для рабочего стола

0 0 0 SCAN TABLE kdtree_nonendpt VIRTUAL TABLE INDEX 1: (~0 rows)
0 0 0 EXECUTE LIST SUBQUERY 1
1 0 0 SCAN TABLE kdtree_nonendpt VIRTUAL TABLE INDEX 2:DaBbDcBd (~0 rows)
0 1 1 SEARCH TABLE kdtree_nonendpt_data USING INDEX sqlite_autoindex_kdtree_nonendpt_data_1 (verid=?) (~1 rows)

Sqlite на рабочем столе был установлен с помощью apt-get, а на android был скомпилирован следующие параметры из источника:

LOCAL_MODULE:= sp_sqlite
LOCAL_CPPFLAGS := -std=c++0x -fexceptions -Werror -DNDEBUG=1 -DDEBUG=0 -O3 -DANDROID -frtti -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4=1 -DSQLITE_THREADSAFE=2

Что может быть причиной того, что sqlite не использует индекс на Android? Verid строки является ПЕРВИЧНЫМ КЛЮЧОМ в обеих таблицах, поэтому не должно быть никакого сканирования, за исключением сканирования, выполненного в подзапросе для rtree.

1 ответ

Я не думаю, что подзапрос необходим. Попробуйте это - планировщик запросов может работать лучше:

SELECT kdtree_nonendpt.verid, minlat, minlon, data

ОТ kdtree_nonendpt, kdtree_nonendpt_data

ГДЕ минлат>=? И maxlat<=?

И минлон>=? И maxlon<=?

AND kdtree_nonendpt.verid = kdtree_nonendpt_data.verid

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