在SQL Server中,'BETWEEN'函数是否非常昂贵?

8

我试图将两个相对简单的表连接在一起,但我的查询经历了严重的挂起。 我不确定为什么,但我认为这可能与“between”函数有关。 我的第一个表看起来像这样(还有很多其他列,但这将是我提取的唯一列):


RowNumber
1
2
3
4
5
6
7
8

我的第二个表"groups"将行分组成“块”,其架构如下:


BlockID     RowNumberStart     RowNumberStop
1           1                  3
2           4                  7
3           8                  8

我希望得到的结果是将行号与块ID进行关联,如下所示,并且与第一个表格具有相同数量的行。因此,结果应该像这样:

RowNumber   BlockID           
1           1
2           1
3           1
4           2
5           2
6           2
7           2 
8           3

为了获得这个结果,我使用了以下查询,并将结果写入临时表中:

select A.RowNumber, B.BlockID
into   TEMP_TABLE
from   TABLE_1 A left join TABLE_2 B
on     A.RowNumber between B.RowNumberStart and B.RowNumberStop

TABLE_1和TABLE_2是非常大的表格。 TABLE_1大约有122M行,而TABLE_2大约有65M行。 在TABLE_1中,RowNumber被定义为“bigint”,而在TABLE_2中,BlockID,RowNumberStart和RowNumberStop都被定义为“int”。 不确定这是否有影响,但只是想包括这些信息。

查询现在已经挂起了八个小时。 类似于此类数据量和类型的查询并不需要花费这么长时间。 所以我想知道是不是“between”语句导致了这个查询的挂起。

绝对欢迎任何关于如何使此过程更加高效的建议。


你看过执行计划了吗? - HLGEM
以前从未在连接中看到过这种用法。 - DForck42
2个回答

9

BETWEEN 只是简写形式,表示:

select A.RowNumber, B.BlockID
into   TEMP_TABLE
from   TABLE_1 A left join TABLE_2 B
on     A.RowNumber >= B.RowNumberStart AND A.RowNumber <= B.RowNumberStop

如果执行计划从B到A(但左连接应该指示它实际上是从A到B),那么我假设TABLE_1在RowNumber上有索引(并且这应该覆盖此查询)。如果它只有一个基于RowNumber的聚集索引,并且表非常宽,我建议仅在RowNumber上使用非聚集索引,因为这样可以在每个页面上放置更多行。
否则,您需要在TABLE_2上对RowNumberStart进行降序或对RowNumberStop进行升序索引,因为对于给定的A,您需要在RowNumberStart上进行DESC匹配。
我认为您可能想将连接更改为INNER JOIN,因为连接条件的设置方式。 (您是否会在没有块的情况下得到TABLE_1?)
如果查看执行计划,您应该会得到更多关于性能不佳的线索,但是停止标准很可能未在TABLE_1中使用。
不幸的是,SQLMenace有关SELECT INTO的答案已被删除。我的评论是针对@Martin的:SELECT INTO性能不如以前那么差,但对于大多数生产环境,我仍然建议使用CREATE TABLE,因为SELECT INTO会推断类型和NULLability。如果您验证它正在执行您认为它正在执行的操作,则这很好,但是创建一个超长的varchar或具有非常奇怪的精度的decimal列不仅可能导致奇怪的表,而且可能会导致性能问题(特别是对于一些大型varchars,当您忘记LEFT或任何其他内容时)。我认为这只是帮助清楚地说明您希望表看起来像什么。通常,我将使用WHERE 0 = 1进行SELECT INTO并检查模式,然后使用我的调整脚本(例如添加IDENTITY或添加具有时间戳默认值的列)。

内连接很有意义,所以我将查询改为了内连接。此外,我按照您的建议使用了索引,查询大约运行了20分钟左右。非常感谢您的帮助! - Bobb

1
你有一个主要问题:你想一次显示太多的数据量。你真的确定你要一次处理表1中全部1.22亿行的结果吗?你真的需要那么多吗?

5
他正在向表中插入数据,而非从表中进行选择。 - SQLMenace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接