Sql 修改表中每一行的最快方法

Sql 修改表中每一行的最快方法,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,更新一个相对较大的表(约7000万行)的推荐方法是什么,以便用当前键间接链接的另一个表的id替换外键列 假设我有三张桌子: Person Id long, Group_id long --> foreign key to Group table Group Id long Device_id long --> foreign key to Device table Device Id long 我想更新Person表,使其具有设备表的直接外键,即: P

更新一个相对较大的表(约7000万行)的推荐方法是什么,以便用当前键间接链接的另一个表的id替换外键列

假设我有三张桌子:

Person
  Id long,
  Group_id long   --> foreign key to Group table

Group
  Id long
  Device_id long  --> foreign key to Device table

Device
  Id long
我想更新Person表,使其具有设备表的直接外键,即:

Person
  Id long,
  Device_Id long  --> foreign key to Device table

Device
  Id long
查询将如下所示:

-- replace Group_id with Device_id
update p from Person p
  inner join Group g
  on g.Id = p.Group_id
set p.Group_id = g.Device_id
select top 1 * from table

DECLARE @MinPK BIGINT
DECLARE @MaxPK BIGINT
SET @MinPK=0
SET @MaxPK=0

WHILE @@ROWCOUNT>0
BEGIN
    SELECT
        @MaxPK=MAX(a.PK)
    FROM (
        SELECT TOP 3
            PK
        FROM Table
        WHERE PK>@MinPK
        ORDER BY PK ASC
    ) a

    --Change this to an update
    SELECT
        PK
    FROM Table
    WHERE PK>@MinPK
    AND PK<=@MaxPK

    SET @MinPK=@MaxPK
END
我将首先删除FK约束,然后重命名该列

这样行吗? 有更好的办法吗? 我能加快速度吗?在运行此查询时,其他所有内容都将脱机,服务器已备份UPS,因此我希望跳过任何事务更新
如果您正确地编写了更新(假设这是SQL Server),那么它将起作用

update p
set p.Group_id = g.Device_id
from Person p
inner join Group g on g.Id = p.Group_id
除此之外,重新使用,然后重命名列*,这是一个非常明智的举动。除非您希望使用WHILE循环和person.Id标记将更新分为多个批,否则无法想出任何智能方法来加快更新速度


*-

除非每组只有一台设备,否则你的想法行不通,这太荒谬了,所以我认为不行

问题是,您必须将许多设备id值塞进person表中的一列中——这就是为什么您首先需要一个group表

删除要更新的表上的索引,并在更新完成后重新创建。 删除要更新的表上的约束,并适当地重新创建。毕竟,更新完成后,您正在更改引用。 关闭要更新的表上的触发器,并在更新完成后启用。 您可能需要考虑运行批处理。我个人会创建一个循环,一次批量更新10k行。这似乎在我的硬件上造成了最少的问题,磁盘空间不足等等。你可以订购更新并跟踪PK,这样你就知道你在哪里了。或创建一个位列,该列在更新特定记录时设置;这种方法可能会使总体上更容易,因为您根本不需要跟踪PK。 此类循环的示例可能如下所示:

-- replace Group_id with Device_id
update p from Person p
  inner join Group g
  on g.Id = p.Group_id
set p.Group_id = g.Device_id
select top 1 * from table

DECLARE @MinPK BIGINT
DECLARE @MaxPK BIGINT
SET @MinPK=0
SET @MaxPK=0

WHILE @@ROWCOUNT>0
BEGIN
    SELECT
        @MaxPK=MAX(a.PK)
    FROM (
        SELECT TOP 3
            PK
        FROM Table
        WHERE PK>@MinPK
        ORDER BY PK ASC
    ) a

    --Change this to an update
    SELECT
        PK
    FROM Table
    WHERE PK>@MinPK
    AND PK<=@MaxPK

    SET @MinPK=@MaxPK
END

我讨厌SQL,哈哈。但批处理评论才是最有趣的。如果我只是通过SSMS运行,我相信它会在实际更新表之前创建一个巨大的事务,使整个过程变慢并占用大量磁盘空间,这是我想要避免的。确实如此,你可以尝试通过google translate:实际上,一个组就像一组人,而不是一组设备,所以,是的,一个组只有一个设备,如问题所示,请检查组表中的设备id列。但实际上,所有查询都需要获取与单个设备相关的所有人员,这需要通过组表进行不必要的连接,我们希望使人员独立于组和任何其他类似元数据。伙计,您应该查看DDL中的链接。他确实努力把它画好了!但是我如何创建这个循环呢?假设我没有跟踪进度的bitcolumn,我将如何跟踪PK?仅仅通过使用不同的查询查看值?