假设我有两个表如下(从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
两个表中的第一行是列标题。我想提取d2
中x
列与d1
匹配且pos1
落在(包括边界值)d1
内的所有行#39; start
和end
列。也就是说,我喜欢结果:
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中执行此操作的最有效方法是什么?
非常感谢。
答案 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)......)