我想优化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
我想优化上面的代码,因为这需要几个小时才能完成。
答案 0 :(得分:0)
我想要点击的关键词有很多。首先,迭代地在SQL中做任何事情(特别是插入数百万行)几乎从来都不是正确的方法。因此,我们需要看看窗外抛出那个模型。
其次,你的方法似乎是循环遍历一组数字数百万次,并在插入的VALUES子句中添加一组新的括号,使你看起来像是一个可笑的长串括号( 1,1,2),(1,2,2)...等等。如果你要迭代地这样做,你想要做到这一点,以便每个循环只是插入而不是建立一个不受约束的插入字符串。
第三,这里没有什么需要动态SQL;不是@max_c的第一个赋值,也不是插入到nptb_data_v7中。您可以静态构造所有这些语句,而无需使用动态sql和a)模糊代码和b)让自己打开注入攻击。
有了这些,现在我们可以开始讨论。所有这些似乎都在创建一个介于1到2百万之间的自动递增数字组合,并根据一些规则,@ i,@ b和当前迭代的值。
这里你需要的第一件事是一个计数表(只是一个大整数表)。有很多方法可以做到这一点,但这里有一个简洁的脚本,可以帮助你开始。
http://www.sqlservercentral.com/scripts/Advanced+SQL/62486/
一旦你制作了这个表,你的脚本就会自动将你新创建的数字/计数表连接到自身,这样你定义的规则就会满足你的插入。由于它不是100%清楚你的代码试图得到什么,我也不能从提供的信息中运行它,这是我必须留给你的地方。如果您可以更好地总结表格的外观,变量声明和目标,我可以帮助您编写一些代码。但希望这可以让你开始。