在SQL中有效地连接区间范围

时间:2014-12-11 22:18:13

标签: mysql sql sqlite query-optimization intervals

假设我有两个表如下(从SO post获取的数据):

d1

 x start end
 a     1   3
 b     5  11
 c    19  22
 d    30  39
 e     7  25

d2

 x pos
 a   2
 a   3
 b   3
 b  12
 c  20
 d  52
 e  10

两个表中的第一行是列标题。我想提取d2x列与d1匹配且pos1落在(包括边界值)d1内的所有行#39; startend列。也就是说,我喜欢结果:

 x pos start  end
 a   2     1    3
 a   3     1    3
 c  20    19   22
 e  10     7   25

到目前为止,我所看到的方式是:

SELECT * FROM d1 JOIN d2 USING (x) WHERE pos BETWEEN start AND end

但我不清楚的是,这项操作是否尽可能高效(即内部优化)。例如,首先计算整个连接并不是真正的可扩展方法IMHO(在速度和内存方面)。

是否还有其他有效的查询优化(例如:使用interval trees)或其他算法可以在SQL中有效地处理范围(同样,在速度和内存方面)我可以使用?如果它使用SQLite,PostgreSQL,mySQL等并不重要。

在SQL中执行此操作的最有效方法是什么?

非常感谢。

1 个答案:

答案 0 :(得分:0)

不确定这一切是如何在内部发挥作用的,但根据具体情况,我建议用一个表来“推出”来自d1的所有值然后加入那个值。通过这种方式,查询引擎可以“精确地”查明正确的记录,而不必找到与要查找的值匹配的边界组合。

e.g。

x value
a  1
a  2
a  3
b  5
b  6
b  7
b  8
b  9
b 10
b 11
c 19 etc..

给出值列(**)的索引,这应该比在原始d1表IMHO上加入BETWEEN start AND end要快得多。

当然,每当你对d1进行更改时,你也需要调整推出的表(触发?)。如果经常发生这种情况,您将花费更多时间来更新推出的表格,而不是首先获得的!此外,如果某些间隔非常大,这可能会占用相当多的(磁盘)空间;而且,这假设我们不需要寻找非整数(例如,如果我们寻找值3.14会怎么样?)

(你可以考虑在这里尝试一个独特的(值,x)......)