我很惊讶加入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
我该怎么做才能加快速度?
答案 0 :(得分:1)
你可以试试的想法。如你所知,每个A只有B中的一个匹配,因为你知道范围不重叠,为什么要看KeyEnd呢?它始终是A记录的最大KeyStart B记录,其中B.KeyStart不大于A.Key。
所以我们得到A,在B中寻找最匹配的StartKey然后访问整个相应的B记录以便读取B.Column。您可以在此处使用SQL Server的CROSS APPLY。
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;
这可能会更快。这可能会慢一点。试试吧。
答案 1 :(得分:0)
这主要比您预期的要慢,因为您希望DBMS知道它不知道的事情。
DBMS不知道没有重叠范围。因此,从DBMS的角度来看,甚至可能是所有B记录的范围从min Key到max Key,这意味着将所有A记录与所有B记录连接起来。只有你知道每张A记录只有一张B记录。
因此,DBMS必须通读所有B,以便找出匹配的内容和不匹配的内容。由于没有WHERE子句,所有记录都是相关的,因此使用索引是不可能的。
您可以通过它理解的约束告诉您所知的所有人,从而帮助DBMS:KeyStart是独一无二的。 KeyEnd是独一无二的。 (你不能说它没有重叠的范围。)也许它会有所帮助,但我实际上对此表示怀疑。
此外,您可以创建包含所有相关值的索引,因此无需读取表本身;将改为读取索引。 Index on tableB(KeyStart, KeyEnd, Column)
。