我需要编写一些代码来插入大约300万行数据 同时我需要插入相同数量的伴随行。
即。 schema看起来像这样:
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);
}
但这不允许我添加相应的“属性”行。
我认为最好的解决方案可能是添加像this one这样的存储过程,它通常允许我进行批量插入(或至少多次插入,但我可能会以某种方式禁用存储过程中的日志记录性能)然后返回相应的ID。
任何人都可以想到更好的(即更简洁,接近相同的性能)解决方案吗?
答案 0 :(得分:3)
将大量数据移入SQL Server的最佳方法是bcp。假设数据在某种文件中启动,您需要编写一个小脚本来将数据汇集到两个表中。或者,您可以使用bcp将数据汇集到一个表中,然后使用SP将数据插入到两个表中。
答案 1 :(得分: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)最后通过使用Item:
连接阶段来加载Property表INSERT INTO Property(FK_ItemID, Value)
SELECT id, Value
FROM stage
JOIN Item ON Item.Title = stage.Title
答案 2 :(得分:2)
将数据批量复制到临时表中,然后调用存储过程,将数据拆分为需要填充的两个表。
答案 3 :(得分:2)
您也可以使用.NET SqlBulkCopy类批量复制代码。