我想在SQL server中优化数百万条记录的插入。
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
我想优化上面的代码,因为它需要几个小时来完成这一点。
发布于 2015-02-05 21:44:38
有相当多的关键的事情我想去碰碰运气。首先,在SQL中迭代地做任何事情(特别是插入数百万行)几乎从来都不是正确的方法。所以现在,我们需要看看如何把模型扔出窗外。
其次,您的方法似乎是遍历一组数字数百万次,并在insert中的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/
一旦创建了这个表,脚本就变成了将新创建的numbers/tally表连接到自身的问题,以便为插入满足您定义的规则。因为不是100%清楚你的代码试图得到什么,我也不能从提供的信息中运行它,这就是我必须让你决定的地方。如果您能更好地总结您的表的外观,您的变量声明和您的目标,我也许能够帮助您编写一些代码。但希望这能让你开始学习。
https://stackoverflow.com/questions/28344500
复制相似问题