我正在桌面和 android 上的 sqlite 数据库上执行以下查询:
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);
这是 android 上面 EXPLAIN QUERY 的结果
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 上的 sqlite 是使用源代码中的以下选项编译的:
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上使用索引的原因可能是什么?行验证是两个表中的主键,因此除了在 rtree 的子查询中完成的扫描之外,不应进行任何扫描。