Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Indexing SQLite R*树索引未与DISTINCT一起使用_Indexing_Sqlite_R Tree_Query Planner - Fatal编程技术网

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

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

在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 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