我正在尝试将两个相对简单的表连接在一起,但我的查询遇到了严重的挂断。我不确定为什么,但我认为它可能与'between'功能有关。我的第一个表看起来像这样(有很多其他列,但这将是我要拉的唯一一列):
RowNumber
1
2
3
4
5
6
7
8
我的第二个表“将”行“分组”为“块”,并具有以下架构:
BlockID RowNumberStart RowNumberStop
1 1 3
2 4 7
3 8 8
我希望得到的结果是将RowNumber与BlockID链接如下,与第一个表的行数相同。所以结果看起来像这样:
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实际上是非常大的表。表1大约是122M行,而TABLE_2大约是65M行。在TABLE_1中,RowNumber被定义为'bigint',而在TABLE_2中,BlockID,RowNumberStart和RowNumberStop都被定义为'int'。不确定是否有所作为,但也只是想包含这些信息。
该查询现已挂了八个小时。对这种类型和数据量的类似查询不会花费这么长时间。所以我想知道是否可能是挂起此查询的'之间'声明。
绝对欢迎任何关于如何提高效率的建议。
答案 0 :(得分: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
如果执行计划从B变为A(但是左连接将表明它必须从A到B,真的),那么我假设TABLE_1在RowNumber上被索引(并且应该覆盖此查询)。如果它只在RowNumber上有一个聚簇索引,并且表格非常宽,我建议只在RowNumber上使用非聚集索引,因为你每页都会适合更多的行。
否则,您希望在RowNumberStart DESC或RowNumberStop ASC上的TABLE_2上建立索引,因为对于给定的A,您需要在RowNumberStart上进行DESC匹配。
我认为您可能希望将加入更改为INNER JOIN,即设置加入条件的方式。 (你有没有得到TABLE_1?)
如果你看看你的执行计划,你应该得到更多关于性能可能不好的原因的线索,但是在寻找TABLE_1时可能没有使用停止标准。
不幸的是,SQLMenace关于SELECT INTO
的答案已被删除。我对此的评论意味着:@Martin SELECT INTO
的效果并不像以前那么糟糕,但我仍然建议{em>大多数制作CREATE TABLE
,因为{{ 1}}将推断类型和可空性。如果您确认它正在执行您认为正在执行的操作,那么这很好,但是创建具有非常奇怪精度的超长SELECT INTO
或varchar
列不仅会导致奇数表,还会导致性能问题(当你忘记LEFT或其他什么的时候特别是那些大的变种。)我认为这有助于明确表达您期望表格的样子。通常我会使用WHERE 0 = 1 SELECT INTO并检查架构,然后使用我的调整编写脚本(例如添加IDENTITY或添加带有时间戳默认值的列)。
答案 1 :(得分:1)
您有一个主要问题:您希望一次显示太多数据量。你真的确定要一次处理表1中所有 122M行的结果吗?你真的需要吗?