我有一个对象列表,这个列表包含大约400万个对象。有一个存储过程,它将对象属性作为参数,进行一些查找并将它们插入表中。
将这400万个对象插入db的最有效方法是什么?
我是怎么做的:
-- connect to sql - SQLConnection ...
foreach(var item in listofobjects)
{
SQLCommand sc = ...
// assign params
sc.ExecuteQuery();
}
这一直很慢。
有更好的方法吗?
这个过程将是一个预定的任务。我会用这个小时运行,所以我确实希望这样的高容量数据。
答案 0 :(得分:8)
根据您的评论,将数据转储到临时表中,然后根据proc进行查找并插入真实表集......它将比逐行快得多
答案 1 :(得分:2)
从C#插入四百万条记录永远不会是理想的,但更好的方法是在代码中构建命令文本,这样你就可以在块中完成。
这几乎不是防弹的,它没有说明如何合并查找(正如你所提到的那样),但基本的想法是:
// You'd modify this to chunk it out - only testing can tell you the right
// number - perhaps 100 at a time.
for(int i=0; i < items.length; i++) {
// e.g., 'insert dbo.Customer values(@firstName1, @lastName1)'
string newStatement = string.Format(
"insert dbo.Customer values(@firstName{0}, @lastName{0})", i);
command.CommandText += newStatement;
command.Parameters.Add("@firstName" + i, items[i].FirstName);
command.Parameters.Add("@lastName" + i, items[i].LastName);
}
// ...
command.ExecuteNonQuery();
答案 2 :(得分:2)
我使用XML获得了很好的结果,可以将大量数据导入SQL Server。像你一样,我最初是一次插入一行,由于应用程序和服务器之间的往返时间,因此我将切换逻辑以传入包含要插入的所有行的XML字符串。插入时间从30分钟缩短到不到5秒。这是几千行。我已经测试了大小为20兆字节的XML字符串,没有任何问题。根据您的行大小,这可能是一个选项。
使用nText类型将数据作为XML String传入。
这样的事情构成了完成工作的存储过程的基本细节:
CREATE PROCEDURE XMLInsertPr(@XmlString ntext)
DECLARE @ReturnStatus int,@ droc int
EXEC @ReturnStatus = sp_xml_preparedocument @hdoc OUTPUT,@ XmlString
IF(@ReturnStatus&lt;&gt; 0)
BEGIN
RAISERROR('无法打开XML文档',16,1,50003)
RETURN @ReturnStatus
END
INSERT INTO TableName
SELECT * FROM OPENXML(@hdoc,'/ XMLData / Data')WITH TableName
END
答案 3 :(得分:1)
您可以考虑删除正在插入的表上的任何索引,然后在插入所有内容后重新创建它们。我不确定批量复制类是如何工作的,但是如果你在每个插件上更新你的索引,它可能会减慢很多东西。
答案 4 :(得分:0)
如果这是一次性操作:不进行优化并在夜间/周末运行