sql-server - SQL Server 中的 'BETWEEN' 函数是否非常昂贵?

标签 sql-server performance between

我正在尝试将两个相对简单的表连接在一起,但我的查询遇到了严重的挂起。我不知道为什么,但我认为这可能与“之间”功能有关。我的第一个表看起来像这样(有很多其他列,但这将是我要拉的唯一列):


RowNumber
1
2
3
4
5
6
7
8

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


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”。不确定这有什么不同,但只是想也包括这些信息。

该查询现已挂起八个小时。对这种类型和数据量的类似查询不会花费这么长时间。所以我想知道是否可能是“Between”语句挂起了这个查询。

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

最佳答案

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,即连接条件的设置方式。 (您是否会在没有任何 block 的情况下获得 TABLE_1?)

如果查看执行计划,您应该会获得更多关于性能可能不佳的原因的线索,但在查找 TABLE_1 时可能不会使用“停止”条件。

不幸的是,SQLMenace 关于SELECT INTO 的回答已被删除。我对此的评论是:@Martin SELECT INTO 性能并不像以前那么糟糕,但我仍然建议 大多数使用 CREATE TABLE 产生式,因为 SELECT INTO 将推断类型和 NULL 性。如果您验证它正在执行您认为它正在执行的操作,那么这很好,但是创建一个超长的 varchar 或一个具有非常奇怪的精度的 decimal 列不仅会导致奇怪的结果表,但性能问题(特别是当你忘记 LEFT 或其他什么时,使用一些大的 varchars)。我认为这有助于明确您期望的表格是什么样子。通常我会使用 WHERE 0 = 1 进行 SELECT INTO 并检查架构,然后使用我的调整编写脚本(例如添加 IDENTITY 或添加具有时间戳默认值的列)。

关于sql-server - SQL Server 中的 'BETWEEN' 函数是否非常昂贵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5582582/

相关文章:

python - 为什么这需要这么长时间才能匹配?它是一个错误吗?

android - TableLayout 与 ConstraintLayout 性能

c# - DocumentDB 查询中的运算符之间

sql - 使用 'between' 和 varchar (sql server)

sql-server - 如何从文件夹中获取最新的文件名?

sql - 添加默认约束的命令

Android:如何找到 SQLITE_MAX_COMPOUND_SELECT

mysql - 列出所有记录并统计它们在 SQL 中的某个日期范围内使用的次数

sql-server - 单一记录 View ,如 PL/SQL Developer

SQLite:获取日期之间的所有日期