SQL - 更新大表(9亿)记录的查询性能

时间:2017-02-12 11:34:01

标签: sql tsql indexing database-performance query-performance

我有一个拥有9亿条记录的数据库表。我需要更新该表中的4个不同的键,通过将它们连接到维度并将事实表的键设置为维度的键。我已经编写了4个不同的SQL脚本(参见下面的示例)来执行更新,但问题是执行时间太长。该查询已运行超过20个小时,我甚至不确定它将走多远,需要多长时间。我有什么办法可以改善这一点,所以只需几个小时即可完成。添加索引会改善这个吗?

UPDATE f
SET f.ClientKey = c.ClientKey
FROM dbo.FactSales f
JOIN dbo.DimClient c
ON f.ClientId = c.ClientId

3 个答案:

答案 0 :(得分:0)

  1. 脚本外键。放下它们。
  2. 更新列的脚本索引(不属于条件)。放下它们。
  3. 如果存在则禁用触发器。
  4. 禁用所有可以锁定的进程(= all,包括选择)。
  5. 更新密钥。
  6. 重新创建外键,索引,启用触发器。
  7. 快乐。
  8. 并评论5 - 仅使用所有新源代码从目标表准备主键并执行一个语句。这意味着连接成本较低,而且只有一个连接。

答案 1 :(得分:0)

可以使用它来填充事务日志

select 1 
while(@@rowcount > 0)
begin 
    UPDATE f
    SET top (100000) f.ClientKey = c.ClientKey
    FROM dbo.FactSales f
    JOIN dbo.DimClient c
    ON  f.ClientId   = c.ClientId 
    AND f.ClientKey != c.ClientKey
end

如果您需要更新4个不同的密钥,请一次全部执行 大部分成本是获取锁定

禁用f.ClientKey,运行更新,然后重建它

如果您确定DimClient不会更改with (nolock)但需要确定

如果您是唯一需要更新FactSales的进程,请使用tablock holdlock

答案 2 :(得分:0)

使用正确的值创建一个新表。之后添加索引,约束。删除现有表,并在可能的情况下将新表重命名为现有表。