我感到惊讶的是,用ON指定的BETWEEN子句连接两个表要花费这么长的时间。在表A中,A.Key是UNIQUE,排序为ascending。在表B中,B.KeyStart和B.KeyEnd列也按升序排序,它们形成排他性间隔,如1-4, 5-6, 7-11等等。
SELECT A.Key, B.Column
FROM tableA as A
INNER JOIN tableB as B
ON A.Key BETWEEN B.KeyStart AND B.KeyEnd我能做些什么来加快速度?
发布于 2015-01-16 15:10:20
一个你可以尝试的想法。正如您所知道的,对于每个A,B中只有一个匹配项,因为您知道范围不会重叠,为什么要看KeyEnd呢?它始终是A记录的最大KeyStart B记录,其中B.KeyStart不大于A.Key。
因此,我们得到A,寻找最佳匹配的StartKey在B,然后访问整个对应的B记录,以读取B.Column。您可以在这里使用Server的交叉应用。
select a.Key, b.Column
from tableA a
cross apply
(
select max(KeyStart) as KeyStart from tableB where tableB.KeyStart <= a.Key
) best
join tableB b on b.KeyStart = best.KeyStart;这可能会更快。这可能会慢一些。试试看吧。
SQL小提琴:http://www.sqlfiddle.com/#!3/58e44/3。
发布于 2015-01-16 14:17:58
这主要比您预期的要慢,因为您希望DBMS知道它不知道的事情。
DBMS不知道不存在重叠范围。因此,从DBMS的角度来看,所有B记录的范围从最小键到最大键,这意味着将所有A记录与所有B记录连接起来。只有你知道每一张唱片只有一张B唱片。
所以DBMS必须读取所有的B,以便找出哪些匹配,哪些不匹配。由于没有WHERE子句,所有记录都是相关的,因此使用索引是不可能的。
您可以通过数据库管理系统所理解的约束来帮助DBMS : KeyStart是唯一的。KeyEnd是独一无二的。(但你不能告诉它没有重叠的范围。)也许有帮助,但我对此表示怀疑。
此外,您可以创建一个包含所有相关值的索引,因此没有必要读取表本身,而是读取索引。Index on tableB(KeyStart, KeyEnd, Column)。
https://stackoverflow.com/questions/27985558
复制相似问题