Indexing SQLite R*树索引未与DISTINCT一起使用
在SQLite 3.20.1中,我创建了一个R*树索引dog_bounds和一个临时表Frisbes,如下所示:Indexing SQLite R*树索引未与DISTINCT一起使用,indexing,sqlite,r-tree,query-planner,Indexing,Sqlite,R Tree,Query Planner,在SQLite 3.20.1中,我创建了一个R*树索引dog_bounds和一个临时表Frisbes,如下所示: -- 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
-- 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
如何获得此处使用的R*树索引?复制狗真是太可惜了 查询优化器认为不同的执行顺序更容易获得不同的dog_id值 将R树查找移动到子查询中,以便强制查询优化器分别执行这两项操作:
SELECT DISTINCT dog_id
FROM (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);
哎呀,查询优化器太聪明了。但是有一些方法可以禁用它规则21:
SELECT DISTINCT dog_id
FROM (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
LIMIT -1);
狗的id总是独一无二的,不是吗?不需要不同的函数调用。@numbluent dog_id在dog_边界中可能是唯一的,但在飞盘重叠查询结果中不是唯一的;非独立查询返回526行,而独立查询返回135行。我明白了,是否可以为飞盘重叠创建一个复合主键并选择“无”独立。。我觉得这样做完全忽略了索引。@numblue飞盘变化非常频繁,它们的重叠无法提前知道我更新了用这个信息剪下的模式,我会尝试使用内部连接 QUERY PLAN |--SCAN TABLE dog_bounds AS db VIRTUAL TABLE INDEX 2: |--SCAN TABLE frisbees AS f `--USE TEMP B-TREE FOR DISTINCT
SELECT DISTINCT dog_id
FROM (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
LIMIT -1);
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