【问题标题】:insert in cycle插入循环
【发布时间】:2012-11-24 12:41:49
【问题描述】:

我在 SQL SERVER 上有一个脚本:

while (@i < 100000)
begin
  insert into TABLE_NAME (id, pid, value)
    values (@i
          , (select top 1 id from TABLE_NAME order by NEWID())
          , 'b')
  set @i += 1;
end;

它执行得非常慢。是否可以做同样的事情但更快? 谢谢。

【问题讨论】:

  • 你想做什么?
  • @MahmoudGamal 我正在尝试生成具有层次结构的表,其中 pid 是 parent_id,对 id 的引用
  • 但问题是如何在我的脚本中更快地在表中插入许多行。)
  • 所以每条记录的parentid都是前一个id??
  • 每个parentId都是之前的id之一

标签: sql sql-server performance insert while-loop


【解决方案1】:

由于子查询,您的查询真的很慢,每次迭代都必须对table_name 进行随机排序。

您可以使用rand()

while (@i < 100000)
begin
  insert into TABLE_NAME (id, pid, value)
    select @i, 
           cast(rand() * @i as int) as pid,
           'b'
  set @i += 1;
end;

这将始终生成一个小于 id 的 pid。

如果这很慢,如果您的数据库处于 FULL 恢复模式并记录所有操作,您可能会减慢速度。

而且,还有这种方法。生成 100,000 个数字,为​​每个数字分配一个随机数,然后将该随机数取模原始数 - 1:

数字为 ( 选择 0 作为数字并集全部 选择 1 个联合全部 选择 2 联合所有 选择 3 联合所有 选择 4 联合所有 选择 5 联合所有 选择 6 联合所有 选择 7 联合所有 选择 8 联合所有 选择 9 ), 数为 ( 选择 (d1.digit*10000+d2.digit*1000+d3.digit*100+d4.digit*10+d5.digit) 作为 val 从数字 d1 交叉连接 数字 d2 交叉连接 数字 d3 交叉连接 数字 d4 交叉连接 数字 d5 ) 选择 val 作为 id, (当 val > 1 然后 seqnum % (val - 1) end) as pid, 'b' 从(选择*, ROW_NUMBER() over (order by newid()) seqnum 从数字 ) s

这在我的机器上运行得非常快。如果没有插入,它会在几秒钟内完成。

【讨论】:

  • "由于子查询,您的查询非常慢,每次迭代都必须对 table_name 进行随机排序。"
  • 我将(通过 NEWID() 从 TABLE_NAME 顺序中选择前 1 个 id)更改为 cast(rand() * @i as int),但它并没有加快脚本速度
  • Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
猜你喜欢
  • 2012-07-10
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多