0

我正在桌面和 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上使用索引的原因可能是什么?行验证是两个表中的主键,因此除了在 r​​tree 的子查询中完成的扫描之外,不应进行任何扫描。

4

1 回答 1

0

我认为不需要子查询。试试这个 - 查询计划器可能会更好:

选择 kdtree_nonendpt.verid、minlat、minlon、数据

FROM kdtree_nonendpt, kdtree_nonendpt_data

在哪里分钟> =?和 maxlat<=?

和米隆>=?和 maxlon<=?

和 kdtree_nonendpt.verid = kdtree_nonendpt_data.verid

于 2014-01-01T05:49:18.293 回答