在BET Server中'BETWEEN'功能是否非常昂贵?

Bob*_*obb 8 sql-server performance between

我正在尝试将两个相对简单的表连接在一起,但我的查询遇到了严重的挂断.我不确定为什么,但我认为它可能与'between'功能有关.我的第一个表看起来像这样(有很多其他列,但这将是我拉的唯一列):


RowNumber
1
2
3
4
5
6
7
8
Run Code Online (Sandbox Code Playgroud)

我的第二个表"将"行"分组"为"块",并具有以下架构:


BlockID     RowNumberStart     RowNumberStop
1           1                  3
2           4                  7
3           8                  8
Run Code Online (Sandbox Code Playgroud)

我想要的结果是将RowNumber与BlockID链接如下,与第一个表的行数相同.所以结果看起来像这样:


RowNumber   BlockID           
1           1
2           1
3           1
4           2
5           2
6           2
7           2 
8           3
Run Code Online (Sandbox Code Playgroud)

为了得到它,我使用了以下查询,将结果写入临时表:


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
Run Code Online (Sandbox Code Playgroud)

TABLE_1和TABLE_2实际上是非常大的表.表1大约是122M行,而TABLE_2大约是65M行.在TABLE_1中,RowNumber被定义为'bigint',而在TABLE_2中,BlockID,RowNumberStart和RowNumberStop都被定义为'int'.不确定是否有所作为,但也只是想包含这些信息.

该查询现已挂了八个小时.对这种类型和数据量的类似查询不会花费这么长时间.所以我想知道它是否可能是挂起此查询的'之间'声明.

绝对欢迎任何有关如何提高效率的建议.

Cad*_*oux 8

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
Run Code Online (Sandbox Code Playgroud)

如果执行计划从B转到A(但是左连接将表明它必须从A到B,真的),那么我假设TABLE_1在RowNumber上被索引(并且应该覆盖此查询).如果它只在RowNumber上有一个聚簇索引并且表格非常宽,我建议仅在RowNumber上使用非聚集索引,因为这样每页会适合更多行.

否则,您希望在RowNumberStart DESC或RowNumberStop ASC上的TABLE_2上建立索引,因为对于给定的A,您需要在RowNumberStart上进行DESC匹配.

我想您可能希望将您的加入更改为INNER JOIN,即设置加入条件的方式.(你是否会在没有阻止的情况下获得TABLE_1?)

如果你看看你的执行计划,你应该获得更多关于性能可能不好的原因的线索,但是在寻找TABLE_1时可能没有使用Stop标准.

不幸的是,SQLMenace关于该问题的答案SELECT INTO已被删除.我的关于这一评论的意思是:@马丁SELECT INTO的表现并不像以前那么糟糕,但我还是建议CREATE TABLE大多数的生产,因为SELECT INTO会推断类型和为空.如果您确认它正在执行您认为正在执行的操作,那么这很好,但是创建超长varchardecimal精度非常奇怪的列不仅会导致奇数表,而且会导致性能问题(尤其是当您忘记时会出现一些大的变量左边或其他).我认为这有助于明确表达您期望表格的样子.通常我会使用WHERE 0 = 1 SELECT INTO并检查模式,然后使用我的调整编写脚本(例如添加IDENTITY或添加默认时间戳的列).