SQL - 插入数百万条记录
问题描述:
我想优化在SQL服务器中插入数百万条记录。SQL - 插入数百万条记录
while @i <= 2000000 begin
set @sql = 'select @max_c= isnull(max(c), 0) from nptb_data_v7'
Execute sp_executesql @sql, N'@max_c int output', @max_c output
set @max_c= @max_c+ 1
while @j <= 10 begin
set @sql_insert = @sql_insert + '(' + cast(@i as varchar) +',' + cast(@b as varchar) + ',' + cast(@max_c as varchar)+ '),'
if len(ltrim(rtrim(@sql_insert)))>=3800
begin
set @sql_insert = SUBSTRING(@sql_insert, 1 , len(ltrim(rtrim(@sql_insert)))-1)
Execute sp_executesql @sql_insert
set @sql_insert = 'insert into dbo.nptb_data_v7 values '
end
set @b = @b + 1
if @b > 100000
begin
set @b = 1
end
set @j = @j + 1
end
set @i = @i + 1
set @j=1
end
set @sql_insert = SUBSTRING(@sql_insert, 1 , len(ltrim(rtrim(@sql_insert)))-1)
Execute sp_executesql @sql_insert
end
我想优化上面的代码,因为它需要几个小时才能完成。
答
有很多关键的事情我想打。首先,在SQL中迭代地执行任何操作(特别是插入数百万行)几乎从来都不是正确的方法。所以,马上我们需要看看把这个模型抛出窗外。第二,你的方法似乎是循环一组数字数百万次,并在插入的VALUES子句中添加一组新的括号,用一个奇怪的长括号括起来,看起来像(1,1,2),(1,2,2)...等等。如果你要迭代地做到这一点,你会想让每个循环只做一个插入而不是构建一个不屈的插入串。
三,这里没有什么需要动态SQL;不是@max_c的第一个赋值,也不是插入nptb_data_v7。您可以静态构造所有这些语句,而不必使用动态SQL,并且a)模糊您的代码,并b)打开自己的注入攻击。
有了这些,现在我们可以下定决心了。所有这些似乎都是在创建一个1到200万的自动递增数的组合,并且根据一些规则,@i,@b和当前迭代的值。
你需要的第一件事是一个理货表(只是一个整数的大表)。有很多方法可以做到这一点,但是这里有一个简洁的脚本,可以帮助你开始。
http://www.sqlservercentral.com/scripts/Advanced+SQL/62486/
一旦你有了这个表中进行,你的脚本成为自加盟新创建的数字/理货表本身,以便您定义的规则都得到满足,你插入的问题。既然它不是100%清楚你的代码试图得到什么,我也不能从所提供的信息中运行它,这是我不得不放弃给你的地方。如果你能提供一个更好的表格,你的变量声明和你的目标,我可以帮你写一些代码。但希望这应该让你开始。
摆脱逐行处理。除非您能够处理更多行,否则它不会很快。 – 2015-02-05 12:57:20
使用SqlBulkCopy:https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx。我希望数百万行花费数秒钟的时间,而不是使用该方法。对于单独的插入,您至少应该将插入批处理到单独的事务中,以避免同步写入SQL Server事务日志。 – 2015-02-05 13:19:04