Mysql SQL中跨区间范围的高效连接
假设我有两个表,如下所示(数据取自此表): 表Mysql SQL中跨区间范围的高效连接,mysql,sql,sqlite,query-optimization,intervals,Mysql,Sql,Sqlite,Query Optimization,Intervals,假设我有两个表,如下所示(数据取自此表): 表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的start和end列中(包括边界值)。也就是说,我希望结果是: x
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
的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
但我不清楚的是,该操作是否尽可能高效(即内部优化)。例如,首先计算整个连接实际上并不是一种可伸缩的方法(就速度和内存而言)
有没有其他有效的查询优化(例如:使用)或其他算法可以有效地处理SQL中的范围(同样,在速度和内存方面),我可以利用它们?不管它是否使用SQLite、PostgreSQL、mySQL等
在SQL中执行此操作最有效的方法是什么
非常感谢。不确定它在内部是如何工作的,但根据具体情况,我建议使用一个表来“滚动”d1中的所有值,然后加入该表。这样,查询引擎就可以“准确地”定位正确的记录,而不必找到与所查找的值匹配的边界组合 e、 g 给定值列(**)上的索引,这应该比在原始d1表IMHO上连接起止点要快得多 当然,每次对d1进行更改时,也需要调整展开的表(触发器?)。如果这种情况经常发生,您将花费比最初更多的时间来更新已展开的表!此外,如果某些间隔非常大,这可能会很快占用相当多的(磁盘)空间;而且,这假设我们不需要寻找非整数(例如,如果我们寻找值3.14会怎么样?)
(您可以考虑在这里使用一个唯一的值(x,x))
如果使用ON代替使用,并将其包含到ON子句中,则会发生什么,即从D1连接D2到D1。x=D2.x和D2.PoT在D1.START和D1之间。另一方面,最好指定该列所属的表,以避免将来将一列添加到与另一列同名的表中时可能出现的查询问题table@cha在一个稍微大一点的数据上,Q中的那个(27秒)比你的(30秒)快。两者(内部)有什么区别?你能给我指一下网上资源吗?我更想知道是否有专门为处理SQL中实现的间隔而设计的算法。非常感谢您的提示。如果单个间隔查找位于索引的最后一列,则通常可以使用“正常”索引对其进行优化。(这里:在d2(x,pos)上创建索引。
)@CL,我不确定我是否完全遵循了,但我创建了您提到的索引,并再次运行了查询。运行时间相同(27秒)。这里是链接,如果你想测试的话。我是data.table R包的R用户和共同开发人员。我们最近使用二进制搜索实现了重叠连接,需要0.7秒。不知道这种情况下是否有这样的加速。根据解释查询计划输出,SQLite使用这个索引是尽可能高效的。我对你测量的细节一无所知。
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..