数据导入场景的高性能架构?

时间:2012-02-09 16:55:24

标签: .net sql-server performance distributed-transactions

我有一个场景,需要将数据从CSV文件通过.NET应用程序导入到数据库服务器(分布式)上的SQL Server 2008。 CSV文件包含 400万条'记录',而目标表可包含 1亿条记录。在插入完成之前,需要根据重复项的现有数据检查正在导入的数据。

我尝试在内存中构建一个DataTable并将其作为参数发送到存储过程,但这表现非常糟糕。

这种情况的好方法是什么?

  • 需要将导入数据(importdata)发送到SQL Server
  • importdata需要再次检查现有数据(existing)是否有重复项
  • 如果existing中只找到一个副本,则需要中止importdata的整个导入

CSV格式

"Name1", "11111111-1111-1111-1111-111111111111"
"Name1", "11111111-1111-1111-1111-111111111111"
"Name1", "11111111-1111-1111-1111-111111111111"

导入数据(DataTable格式示意图):

Table (
    name nvarchar(20),
    someId uniqueidentifier
)

SQL Server上的目标表(示意图):

Table (
    id int primarykey,
    name nvarchar(20),
    someId uniqueidentifier
)

3 个答案:

答案 0 :(得分:1)

我会创建一个临时表来批量导入所有CSV记录:

BULK
INSERT CSVTEMP
FROM 'c:\csvfile.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
GO

然后创建一个存储过程以从CSVTEMP插入到目的地,执行所有检查。

答案 1 :(得分:1)

我会做什么。 。

  1. 使用SqlBulkCopy类我将400万行插入到 数据库到一个临时表(或一个永久的表,但 仅用于此目的)。
  2. 编写一个针对另一个表运行一个表的Proc,并且仅插入 行适当地到目的地表。
  3. SqlBulkCopy类是迄今为止将数据导入MS SQL DB的最快方法,然后让数据库进行更新,这是它擅长的。

    更新这可以在交易中完成吗?

    是的,但我不想设想一项涉及400万行插入和更新400万行的交易。

    如果您使用真正的临时表(例如#MyTempStrore),那么当您在数据库上完成该会话时,临时表将被删除(例如dbConn.Close())。<登记/> 如果使用permant表,则可以创建唯一的会话ID,插入具有该Id的所有行,并将该Id传递给存储的proc。然后,您可以根据需要从表中清除这些ID(或者只是截断表格)。

    希望这有帮助。

答案 2 :(得分:0)

检查SQLBulkCopy和SqlBulkCopyOptions.CheckConstraints。您可以在目标表上直接使用SQLBulkCopy,并在发生重复键时回滚所有更改。