BULK生成数据SQL Server

时间:2015-06-09 19:19:09

标签: sql-server bulkinsert sqlbulkcopy bulk

我需要将伪数据创建到跟随此伪代码的fakeData表中:

foreach(t1.id in table1)
   foreach(t2.id in table2)
      foreach(t3.id in table3)
        INSERT INTO fakeData (t1.id, t2.id, t3.id, random(30,80))

其中id是该表的主键。

我需要尽快做到这一点,因为我计划插入数十亿条记录。我不确定使用SQL来执行语句是最好的方法,还是使用c#或将这些数据放入表中的最佳选择。

这个问题实际上有两个部分,我如何在SQL Server中执行psuedocode,以及最快速地执行此操作的最佳方法是什么。 (我目前没有设置索引)

这似乎与所有其他“最快的批量插入方式”重复。我认为这个问题是不同的,因为我加载的数据实际上可以生成我的SQL Server,所以BULK生成与BULK INSERT相比

PS:我有SQL Server 2012

修改:更多数据

这是一个星型模式。 fakeData将是事实表。

table2是20年的日期维度,有7300条记录。 table3是96条记录的时间维度。 table1是另一个有1亿条记录的维度。

3 个答案:

答案 0 :(得分:0)

您可以使用BCP快速插入数据。如果您的PK列是标识列,它仍然有效。如果没有,那么你可以跳过BCP部分,只需插入while循环。

要创建BCP文件:

  1. 在for循环中,使用固定的#行(比如100万行)快速填充表格。
  2. 将数据BCP输出到BCP文件中。
  3. 将数据BCP重新输入任意次数
  4. 为每个必要的表(下面的伪代码)执行此操作:

    实施例:      - 如果这是开发机器,那么我会将恢复模型更改为简单,      - 如果还没有,减少记录量。然后改回来      - 以前的情况

    BEGIN TRAN
    
    declare @x int = 1
    while @x <= 1000000
    begin
        insert into t1 (col1, col2) values (rand() * 100, rand(123) * 100)
    
        if (@x % 10000) = 0
        begin
            COMMIT TRAN
            BEGIN TRAN
        end
    
        set @x = @x + 1
    end
    
    COMMIT TRAN
    

    然后,bcp输出数据(来自命令提示符)以创建bcp文件

    bcp out [dbname].dbo.t1 c:\file1.bcp -T
    

    现在,根据需要bcp(从命令提示符)数据

    bcp in [dbname].dbo.t1 c:\file1.bcp -T
    bcp in [dbname].dbo.t1 c:\file1.bcp -T
    bcp in [dbname].dbo.t1 c:\file1.bcp -T
    bcp in [dbname].dbo.t1 c:\file1.bcp -T
    bcp in [dbname].dbo.t1 c:\file1.bcp -T
    

答案 1 :(得分:0)

第一部分很简单;

Insert Into FakeData
Select T1.id as T1ID, T2.id as T2ID, T3.id as T3ID
From Table1 T1, Table2 T2, Table3 T3

这将执行三个表的笛卡尔连接并返回所有可能的组合。但是,如果您正在谈论数十亿种可能的组合,那么批处理可能是一个好主意。我会使用偏移量提取,因为它很容易理解,但你可能会找到一种更高效的方式,我也会将结果存储在临时表中,所以你只能运行连接一次和休息是选择和插入。

Declare @BatchSize int = 100000
Declare @RowsToBeInserted bigint = 
((select count(1) as t1count from Table1) * 
(select count(1) as t2count from Table2) * 
(select count(1) as t3count from Table3))
Declare @Iterations int = 0
Declare @CompletedRowCount bigint = 0

Select T1.id as T1ID, T2.id as T2ID, T3.id as T3ID
Into #TempTable
From Table1 T1, Table2 T2, Table3 T3

While @CompletedRowCount < @RowsToBeInserted
begin

Insert into FakeData
select T1ID, T2ID, T3ID
Order by T1ID, T2ID, T3ID
Offset @CompletedRowCount
Fetch next @BatchSize Only
set @Iterations = @Iterations + 1
set @CompletedRowCount = @Iterations * @BatchSize

end

这应该允许您拨打批量大小以适合您的服务器。如果没有设置索引,您不需要删除它们并重新创建它们以提高性能。希望能指出你正确的方向。

答案 2 :(得分:0)

好吧......因为没有人真正展示过如何做随机值。我到目前为止贡献我的解决方案我现在正在做这个,简单的恢复模型:

BEGIN TRAN

declare @x int = 1
while @x <= 5000
begin
INSERT INTO dimSpeed
Select T1.id as T1ID, T2.DateValue as T2ID, T3.TIME_ID as T3ID, ABS(Checksum(NewID()) % 70) + 20
From lines T1, dimDate T2, dimTime T3
WHERE T1.id = @x AND T2.DateValue > '1/1/2015' AND T2.DateValue < '1/1/2016'

    if (@x % 100) = 0
    begin
        COMMIT TRAN
        BEGIN TRAN
    end

    set @x = @x + 1
end

COMMIT TRAN

其中5000是我插入的TABLE1(t1)的元素数。只做5000分钟需要5分钟左右。按此速率,需要 70天才能插入我需要的所有数据。 肯定需要更快的选项