2010-07-22 133 views
0

公司每天都会将包含潜在许多记录(350,000)的文本文件放到我们的安全FTP上。我们已经创建了一个在早期运行的Windows服务,以便将文本文件读入我们的SQL Server 2005数据库表中。我们不做BULK插入,因为数据是关系数据,我们需要根据数据库中已有的数据进行检查,以确保数据保持正常和一致。大数据服务体系结构

问题在于服务可能需要很长时间(小时)。这是有问题的,因为它插入和更新到表中,这些表经常需要由我们的应用程序查询和扫描,这可能会影响数据库和应用程序的性能。

我们想到的一个解决方案是使用与我们的实时数据库相同的表在单独的数据库上运行服务。服务完成后,我们可以在活动数据库中执行BCP,以反映由服务创建的所有新记录。

我从来没有在数据库中处理过数百万条记录,我不确定这样的标准方法是什么。这是做这种事情的适当方式吗?有什么建议么?

回答

2

我见过的一种机制是将值插入临时表 - 与目标表具有相同的模式。空ID表示新记录,填充ID表示更新的记录。然后使用SQL合并命令将其合并到主表中。合并将比个别插入/更新执行得更好。

单独执行此操作会导致对表格上的索引进行维护 - 如果它对选择进行了调整,则花费可能会很高。我相信合并它的一项大规模行动。

它在这里感动: What's a good alternative to firing a stored procedure 368 times to update the database?

大约有SQL合并MSDN文章,所以谷歌搜索将帮助你。

更新:事实证明,你不能合并(你可以在2008年)。你有另一个数据库的想法通常由SQL复制来处理。我再次在生产中看到用于执行长时间运行的操作(在此实例中报告和聚合数据)的当前数据库的副本,但是没有合并回去。我不知道可用的合并功能在SQL复制 - 但它是一个很好的地方看。

要么,要么解决你无法批量插入/更新的原因。

更新2:正如在注释中提到的那样,您可以坚持使用临时表的想法将数据导入数据库,然后在该表中插入/更新连接以填充主表。现在不同的是,SQL正在使用一个集合,因此可以相应地调整任何索引重建 - 即使加入也应该更快。

更新3:您可能会从插入过程中删除数据检查并将其移至服务。如果您可以在发生这种情况时停止插入表格,那么这将允许您解决阻止您进行批量插入的问题(即,您正在根据列值检查重复项,因为您还没有奢侈品ID)。或者用临时表的想法,你可以添加一个WHERE先看看情况,如果在数据库中存在该行,是这样的:

INSERT INTO MyTable (val1, val2, val3) 
SELECT val1, val2, val3 FROM #Tempo 
WHERE NOT EXISTS 
( 
    SELECT * 
    FROM MyTable t 
    WHERE t.val1 = val1 AND t.val2 = val2 AND t.val3 = val3 
) 
+0

+1 350.000行的批量插入应该在不到一分钟内完成。 'merge'在2005年不可用,但是从这个问题来看,插入RealTable(col1,col2)从TempTable中选择col1,col2在这里可以工作 – Andomar 2010-07-22 15:12:21

+0

啊我没有注意到标签 - 我会修改我的答案。不幸的是,OP还表示他不能批量插入。 – 2010-07-22 15:13:14

0

在开始复制和复制数据(这是复杂且昂贵的)之前,检查现有服务以确保其有效运行是值得的。

也许有表格扫描,你可以通过添加一个索引或删除查找查询,你可以通过做聪明的错误处理摆脱?分析您的服务执行并优化这些查询的执行计划。

2

我们做更大的进口比所有的时间。创建一个SSIS pacakge来完成这项工作。我个人更喜欢创建一个临时表,清理它,然后进行更新或导入。但是如果你想在插入之前进行清理,SSIS可以完成所有的清理工作。