SQL Server / SSIS更新太慢

时间:2014-04-23 16:12:48

标签: sql sql-server-2008 stored-procedures ssis

我有一个拥有超过20万用户的sql server 2008表,每个用户都有一个唯一的用户ID,但是有重复的电子邮件地址。

e.g。

email               userid
me@hotmail.com      12345
me@hotmail.com      678910
me@hotmail.com      111213

用户标识跨越各种sql服务器上的各种表(2008,2005,2000)。我们希望合并用户 - 因此我们最终得到一个电子邮件地址和一个选定的用户ID(我已经有一个选择正确用户ID的过程)。

问题是,在SSIS中花费4分钟来更新每个用户(使用sprocs扫描查找旧用户标识的表并更新到我们想要保留的用户)。解决这个问题意味着整个过程需要615天!

还有其他方法吗?

非常感谢您提供的任何帮助或建议! 感谢

2 个答案:

答案 0 :(得分:2)

假设您希望获得最新的ID:

update
   TableContainingUserIDs
set
userid = IDTOKeep
from
TableContainingUserIDs
inner join (
    select max(userid) over (partition by email) as IDToKeep, userid as OldUserID
    from
    tbl
) KeeperSet
on KeeperSet.userid = TableContainingUserIDs.userID

如果您有其他一些选择获胜者ID的逻辑,请创建一个查询或一个包含格式数据的临时表

IDToKeep OldUserID

然后用查询/表替换该查询中的KeeperSet别名。

然后用用户ID冲洗并重复每个辅助表。

如果您使用SSIS而不是存储过程,为什么不使用临时表然后一次更新?

  1. 创建数据流任务。将IDToKeep OldUserID查询/表作为分阶段表推送到目标服务器。
  2. 使用分段表作为KeeperSet,创建一个执行SQL任务并对目标服务器运行上述查询。
  3. 完成后删除KeeperSet暂存表。
  4. 存储过程并不慢,问题是在逐行的数据流任务结束时运行OLEDB命令完全违背了数据库和集合理论的目的。将数据转移到同一个数据库,运行一个基于集合的查询,然后就完成了。

答案 1 :(得分:0)

我认为第一步是创建一个临时参考数据表,例如:

fromId toId
-------------
1234   34567
1235   34567
1236   789

等...

然后将此数据加载到每个数据库实例中。

然后使用游标依次选择每个记录,并根据需要更新的每个表的游标运行更新语句。

然后,此过程全部在SQL中并在同一台计算机内运行。它也可以跨服务器和实例并行运行。