3

我需要编写一些代码来插入大约 300 万行数据。
同时我需要插入相同数量的伴随行。

即架构如下所示:

Item
  - Id
  - Title

Property
  - Id
  - FK_Item
  - Value

我的第一次尝试是这样的:

BaseDataContext db = new BaseDataContext();
foreach (var value in values)
{
    Item i = new Item() { Title = value["title"]};
    ItemProperty ip = new ItemProperty() { Item = i, Value = value["value"]};
    db.Items.InsertOnSubmit(i);
    db.ItemProperties.InsertOnSubmit(ip);
}
db.SubmitChanges();

显然这非常慢,所以我现在使用这样的东西:

BaseDataContext db = new BaseDataContext();
DataTable dt = new DataTable("Item");
dt.Columns.Add("Title", typeof(string));
foreach (var value in values)
{
    DataRow item = dt.NewRow();
    item["Title"] = value["title"];
    dt.Rows.Add(item);
}
using (System.Data.SqlClient.SqlBulkCopy sb = new System.Data.SqlClient.SqlBulkCopy(db.Connection.ConnectionString))
{
    sb.DestinationTableName = "dbo.Item";
    sb.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Title", "Title"));
    sb.WriteToServer(dt);
}

但这不允许我添加相应的“属性”行。

我认为最好的解决方案可能是添加一个像这样的存储过程,它通常可以让我进行批量插入(或至少多次插入,但我可能会以某种方式禁用登录存储过程以提高性能),然后返回对应的id。

谁能想到更好的(即更简洁,性能几乎相同)的解决方案?

4

4 回答 4

3

将这么多数据移动到 SQL Server 中的最佳方法是 bcp。假设数据从某种文件开始,您需要编写一个小脚本将数据汇集到两个表中。或者,您可以使用 bcp 将数据汇集到单个表中,然后使用 SP 将数据插入到两个表中。

于 2009-09-06T13:25:58.210 回答
3

要结合之前最好的两个答案并添加 ID 的缺失部分:

1) 使用 BCP 将数据加载到这样定义的临时“暂存”表中

CREATE TABLE stage(Title AS VARCHAR(??), value AS {whatever});

稍后您将需要适当的索引来提高性能:

CREATE INDEX ix_stage ON stage(Title);

2) 使用 SQL INSERT 加载 Item 表:

INSERT INTO Item(Title) SELECT Title FROM stage;

3)最后通过加入阶段与项目加载属性表:

INSERT INTO Property(FK_ItemID, Value)
SELECT id, Value
FROM stage
JOIN Item ON Item.Title = stage.Title
于 2009-09-06T13:58:40.540 回答
2

将数据批量复制到临时表中,然后调用存储过程,将数据拆分为您需要填充的两个表。

于 2009-09-06T13:39:55.850 回答
2

您也可以使用 .NET SqlBulkCopy 类批量复制代码。

于 2009-09-06T14:05:46.657 回答