使用外键更新SQL表中数百万条记录的最佳方法
我有一个数据库,有几个表,每个表包含数百万条记录。 每年我们都会收到一组用于更新表格的CSV文件。这是一个刷新,而不仅仅是一个附加。 一些表具有返回到其他表的外键。 要在不使用FK的情况下更新表,我只需截断数据库表,创建一个新的临时表,将所有新数据加载到临时表中,并将其插入数据库表中。一切都很好,而且相当快 当我需要更新具有FK的表中的数据时,就会出现问题,因为我不能再简单地截断该表,所以需要一种更新现有表行的方法。 我通过循环中运行的SQL update语句来实现这一点,每次运行一行。它可以工作,但需要13天来处理数百万条记录。 一定有更快的办法使用外键更新SQL表中数百万条记录的最佳方法,sql,database,vb.net,Sql,Database,Vb.net,我有一个数据库,有几个表,每个表包含数百万条记录。 每年我们都会收到一组用于更新表格的CSV文件。这是一个刷新,而不仅仅是一个附加。 一些表具有返回到其他表的外键。 要在不使用FK的情况下更新表,我只需截断数据库表,创建一个新的临时表,将所有新数据加载到临时表中,并将其插入数据库表中。一切都很好,而且相当快 当我需要更新具有FK的表中的数据时,就会出现问题,因为我不能再简单地截断该表,所以需要一种更新现有表行的方法。 我通过循环中运行的SQL update语句来实现这一点,每次运行一行。它可以工
如何一次快速更新多个数据库表行(比如3500),其中每行有8列需要更新?1列是FK,加上其他3列不会改变。我认为你最好的选择是:
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]
我认为你最好的选择是:
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]
我认为你最好的选择是:
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]
我认为你最好的选择是:
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]
只是想一想,对于性能问题,您的sql更新应该使用操作符
或,同时使用更精确的sql筛选器。不使用或操作符。只有几百万个循环。这可能不是最好的方法,但我已经见过了。您只需在启动流程之前删除FK,然后再将其添加回。如果你的CSV文件中有坏数据,可能会把你搞得一团糟。@Malcom,将一百万个循环放到程序脚本中会有好处。在重新加载之间会有多少数据变化?插入新数据、更新已修改的现有数据以及删除/禁用不在新数据集中的数据可能更有效。考虑到性能问题,您的sql更新应该使用运算符或,同时使用更精确的sql筛选器。无或运算符。只有几百万个循环。这可能不是最好的方法,但我已经见过了。您只需在启动流程之前删除FK,然后再将其添加回。如果你的CSV文件中有坏数据,可能会把你搞得一团糟。@Malcom,将一百万个循环放到程序脚本中会有好处。在重新加载之间会有多少数据变化?插入新数据、更新已修改的现有数据以及删除/禁用不在新数据集中的数据可能会更有效