我们有一个C#程序,每晚从数千个网站上抓取数据,并将结果写入一个包含30列的数据库表。其中一个列(称为TEXT)是一个" catch-all"非结构化数据列,可以包含从网站的文本句子到多个段落的任何内容。夜间过程产生大约200万条记录。
它目前设置为使程序将所有记录写入" hold"表在单独的SQL Server实例中。然后我们的主表,从前一天保存了所有200万条记录,完全被截断。然后保持表将所有数据发送到主表。
因此,我们每天都会完整删除并重写所有记录。除此之外,必须有一种更有效的方法来做到这一点。我想跳过看似不必要的中间步骤,让程序直接写入主表。但我能想象的唯一方法就是在记录不存在的情况下追加记录。这看起来令人生畏,因为柱状数据在记录与记录之间存在极大的不一致(就可能有数据而可能没有数据而言可能没有),但也许我会过度思考它。
我已经阅读并考虑了这篇文章中的答案:How do I add a record only if it doesn't already exist in SQL Server?但我不认为答案可以满足我们的需求:它似乎只能在一个字段上使用显式的WHERE子句,其值是手动指示的。
答案 0 :(得分:2)
假设:
stg.MyTable
(stg
是架构)dbo.MyTable
以下是两种获取数据的方法:
一个。 TRUNCATE / INSERT
此方法实际上使用一些CPU和磁盘来复制数据,但它保留了所有表索引,键pk等,并且不要求表格相同
TRUNCATE TABLE dbo.MyTable
INSERT INTO dbo.MyTable (Field1, Field2, Field3)
SELECT Field1, Field2, Field3 FROM stg.MyTable
-- Optional step: clear the staging to free up space
TRUNCATE TABLE stg.MyTable
B中。架构交换
这是有效旋转桌子下方的许多方法之一。许多不同的人似乎孤立地提出了这个问题。它有以下限制:
根据您的描述,我不明白表格是否相同
这是基于发现的优秀描述(包括图表!) http://www.sqlservercentral.com/articles/SQL+Server/149123/
总之你:
将实时表格切换到保留区域以保留它:
alter schema holding transfer dbo.Table
将临时表切换为实时 - 您现在已加载数据
alter schema dbo transfer stg.Table
将表格保持在准备好接受数据的阶段
alter schema stg transfer holding.Table
请注意,这会破坏触发器和外键之类的内容,因此您需要考虑这些内容。
请记住,您现在需要对两个表进行列和索引更改。另一种方法是将索引和PK脚本放在一边并重新应用