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