使用外键更新SQL表中数百万条记录的最佳方法

时间:2014-06-24 01:52:27

标签: sql database vb.net

我有一个包含多个表的数据库,每个表包含数百万条记录。 每年我们都会收到一组CSV文件,用于更新表格。这是一次刷新而不仅仅是追加。 某些表将外键返回到其他表。 要更新没有FK的表,我只是截断数据库表,创建一个新的临时表,将所有新数据加载到临时表中并将其插入数据库表。一切都很好,相当快。

当我需要更新具有FK的表中的数据时出现问题,因为我不能再简单地截断表,因此需要一种方法来更新现有的表行。 我是通过循环运行的SQL更新语句来做到这一点,一次一行。它可以工作,但需要大约13天来处理几百万条记录。 必须有一个更快的方法!

如何一次快速更新多个数据库表行(比如3,500),每行有8列需要更新? 1列是FK,加上3个其他列不会改变。

1 个答案:

答案 0 :(得分:3)

我认为你最好的选择是:

  1. 删除外键约束。
  2. 截断外键表。
  3. 截断主键表。
  4. 从包含主键数据的CSV文件插入主键表。
  5. 将外键数据插入新的临时表。
  6. 内部将外键临时表连接到相关字段上新填充的主键表。
  7. 将该结果插入最终外键表。
  8. 在外键表上重新创建外键。
  9. 使用一些动态SQL,您可以创建存储过程并将表名,文件名和外键名作为参数传递给proc。然后冲洗并重复每组相关表格。

    即使没有存储过程,也应该花费不到13天的时间:)

    更新可能的例子

    ALTER TABLE [SecondaryTable] DROP CONSTRAINT [NameOfForeignKey]
    
    TRUNCATE TABLE [SecondaryTable]
    
    TRUNCATE TABLE [PrimaryTable]
    
    BULK INSERT [PrimaryTable]
    FROM 'C:\PrimaryCSVfile.csv' WITH (FIELDTERMINATOR =',', ROWTERMINATOR ='\n', FIRSTROW = 1)
    
    -- [TempTableSecondary] is a structural copy of [SecondaryTable]
    CREATE TABLE [TempTableSecondary] (column1, column2, ..., columnX)
    
    BULK INSERT [TempTableSecondary]
    FROM 'C:\SecondaryCSVfile.csv' WITH (FIELDTERMINATOR =',', ROWTERMINATOR ='\n', FIRSTROW = 1)
    
    INSERT INTO [SecondaryTable]
    SELECT [TempTableSecondary].*
    FROM [TempTableSecondary]
        INNER JOIN [PrimaryTable] ON [TempTableSecondary].PrimaryKeyFieldName = [PrimaryTable].ForeignKeyFieldName
    
    ALTER TABLE [SecondaryTable] WITH CHECK ADD CONSTRAINT [NameOfForeignKey] FOREIGN KEY([PrimaryKeyFieldName])
    REFERENCES [PrimaryTable] ([ForeignKeyFieldName])
    
    ALTER TABLE [SecondaryTable] CHECK CONSTRAINT [NameOfForeignKey]
    
    DROP TABLE [TempTableSecondary]