sql - 带有 many-ISNULL 的多列 UPDATE-JOIN 需要很长时间?

标签 sql sql-server-2008 join isnull

我们的数据库中有一个存储过程,它通过使用 where 条件连接 30 列上的 2 个表来更新表。 SQL 的一般格式为:

UPDATE Target
SET col1 = Source.col1
INNER JOIN Source 
on 
ISNULL(Target.Col2, '') = ISNULL(Source.Col2, '') and
ISNULL(Target.Col3, '') = ISNULL(Source.Col3, '') and
.
.
.
ISNULL(Target.Col31, '') = ISNULL(Source.Col31, '') and 

这是查询计划。将其保存到您的 PC 并重新打开,以便更好地扩展。

enter image description here

源表有 65M 条记录,目标表有 165M 条记录。以前它曾经在几分钟内运行。考虑到查询是多么丑陋和潜在的低效,我觉得这令人惊讶。这个月它运行了 1.5 小时,使用了 100% 的处理器,我们不得不杀死它。

任何建议如何即兴编写以下查询并使其按时运行..?

我们在 30-col 连接条件中使用的一些列上有单列索引。

我知道 ISNULL 函数和 30 列上的连接很疯狂,这是一个糟糕的设计。别怪我,我继承了这个经济。

不幸的是,没有时间重新设计。有什么建议?

最佳答案

  • 请贴一张预估执行计划的截图
  • 我怀疑以前查询使用了散列连接(它应该使用),但不知何故,基数估计现在出错了,您会得到一个循环连接。在查询上添加一个散列连接提示,看看它是否解决了这个问题 ( INNER HASH JOIN )。一旦我们有了确切的计划,我们就可以说更多。
  • 将等式更改为 (A1 = A2 OR (A1 IS NULL AND A2 IS NULL)) . SQL Server 实际上识别了这种模式,并在内部将其转换为“没有愚蠢的空语义的完全等于”。即使使用空值,您也可以通过这种方式查找索引。

  • 如果这没有帮助,请务必执行步骤 (3) 并在 col2-col31 上创建一个覆盖索引,包括 col1。这将为您提供一个合并连接,这是在这种情况下最有效的计划。它真的很快。警告:这将使表的磁盘大小加倍并减慢更新速度。

    关于sql - 带有 many-ISNULL 的多列 UPDATE-JOIN 需要很长时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10422221/

    相关文章:

    sql-server - 我可以授予数据库用户在架构中创建 View 的权限吗?

    mysql - 在 mysql 中连接两个给定的查询集

    mysql - 优化连接查询以从 A 获取数据,条件是 B 按 B 排序

    mysql - 左外连接和 OR 子句速度很慢。筛选后可以加入吗?

    sql - SQL 中一组 100 列的每行最大值

    mysql - 按顺序条件对表格进行排序?

    sql-server - 如何使用 T-SQL 列出 Sql Server 2008 上的所有 SSIS 包

    sql - 选择查询,其中具有相同 ID 的行仅返回具有最新日期字段的行

    mysql - MYSQL 查询中 GROUP_CONCAT 的替代方案

    sql - 插入字节数组 INTO varbinary(max) 记录