sql server更新查询非常慢

kb5ga3dv  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(476)

我想在一个有c.200m记录的表上创建一个简单的update语句。然而,这似乎需要很长时间。

UPDATE a
SET hybrid_trade_flag = CASE WHEN b.trade_id IS NOT NULL THEN 'Y' ELSE 'N' END
FROM [tbl_master_trades] a
LEFT JOIN [tbl_hybrid_trades_subset] b
    ON a.trade_id = b.trade_id

第一张table tbl_master_trades 拥有约200万条记录,并在上创建了索引 trade_id 和另一列(一起)。第二张table tbl_hybrid_trades_subset 大约有20万。在我不得不取消之前,这个查询运行了40多分钟(取消本身大约需要30分钟)。
我想也许把第二个表转换成一个临时表并拆分语句会有所帮助,所以把它转换成以下内容:

UPDATE a
SET hybrid_trade_flag = 'Y'
FROM [tbl_master_trades] a
INNER JOIN #tmp_hybrid_trades b
    ON a.trade_id = b.trade_id

UPDATE a
SET hybrid_trade_flag = 'N'
FROM [tbl_master_trades] a
WHERE hybrid_trade_flag IS NULL

即使是上述两个查询也需要30分钟才能运行。我需要在第一个表上运行几个这样的更新(c.80),所以我不确定这是否可行,因为这需要几天的时间!有人能告诉我是否/如何加快这一进程吗?

r7xajy2e

r7xajy2e1#

我将首先重写查询以使用 exists :

update t
set hybrid_trade_flag = case 
    when exists(select 1 from tbl_hybrid_trades_subset ts where ts.trade_id = t.trade_id)
    then 'Y'
    else 'N'
end
from tbl_master_trades t

那么,我推荐一个关于 tbl_hybrid_trades_subset(trade_id) 因此子查询可以快速执行。
索引 tbl_master_trades(trade_id) 可能也会有帮助(索引中没有任何其他列),但是子查询地址所在表上的索引似乎更重要。
也就是说,2亿行仍然有大量的行要处理,因此无论如何查询可能会花费相当多的时间。

mwecs4sa

mwecs4sa2#

你遇到了两个问题
您正在检查另一个表中是否存在c.200m值
您正在更新基表中的c.200m值
为了解决这个问题你可以
将适当的索引添加到查找表中
避免在不严格需要的地方进行更新
有问题的索引是

CREATE INDEX idx_trade_id ON tbl_hybrid_trades_subset (trade_id)

要限制更新量,请使用以下命令:

UPDATE a
   SET hybrid_trade_flag = CASE WHEN b.trade_id IS NOT NULL THEN 'Y' ELSE 'N' END
  FROM [tbl_master_trades] a
  LEFT OUTER JOIN [tbl_hybrid_trades_subset] b
               ON b.trade_id = a.trade_id
 WHERE hybrid_trade_flag != CASE WHEN b.trade_id IS NOT NULL THEN 'Y' ELSE 'N' END

第一次可能还需要一段时间,但随后的更新应该会快一点。

相关问题