SQLite R *树索引不与DISTINCT一起使用

时间:2018-05-30 18:28:29

标签: indexing sqlite r-tree query-planner

在SQLite 3.20.1中,我有一个R * Tree索引(realloc)和一个临时表(dog_bounds),如下所示:

frisbees

查询使用此索引很快,如下所示:

-- Changes infrequently and has ~100k entries
CREATE VIRTUAL TABLE dog_bounds USING rtree (
    dog_id,
    min_x, max_x,
    min_y, max_y
);

-- Changes frequently and has ~100 entries
CREATE TEMPORARY TABLE frisbees (
    frisbee_id,
    min_x, max_x,
    min_y, max_y
);

但是,如果我选择EXPLAIN QUERY PLAN SELECT dog_id FROM dog_bounds AS db, frisbees AS f WHERE db.max_x >= f.min_x AND db.max_y >= f.min_y AND db.min_x < f.max_x AND db.min_y < f.max_y; 0|0|1|SCAN TABLE frisbees AS f 0|1|0|SCAN TABLE dog_bounds AS db VIRTUAL TABLE INDEX 2:D1D3C0C2 ,则不再使用索引,即使在DISTINCT(dog_id)之后查询也会变慢:

ANALYZE

我如何获得此处使用的R *树索引?复制狗会很遗憾!

1 个答案:

答案 0 :(得分:2)

查询优化器认为不同的执行顺序可以更容易地获得不同的val list=List("banana,QS,1,0,0", "apple,EE,1,2,1", "peas,US,1,4,4") 值。

将R树查找移动到子查询中,以便强制查询优化器分别执行这两项操作:

val list=List("banana,QS,0,1,0",
"apple,EE,1,1,2", 
"peas,US,4,1,4")
QUERY PLAN
|--SCAN TABLE dog_bounds AS db VIRTUAL TABLE INDEX 2:
|--SCAN TABLE frisbees AS f
`--USE TEMP B-TREE FOR DISTINCT

糟糕,查询优化器过于聪明且flattened the subquery。但有一些方法可以禁用它(规则21):

dog_id
QUERY PLAN
|--CO-ROUTINE 0x892A90
|  |--SCAN TABLE frisbees AS f
|  `--SCAN TABLE dog_bounds AS db VIRTUAL TABLE INDEX 2:D1D3C0C2
|--SCAN SUBQUERY 0x892A90
`--USE TEMP B-TREE FOR DISTINCT