在项目开发过程中,经常需要生成大量的测试数据以进行性能测试或其他测试。传统的数据生成方法可能会非常耗时,本文将介绍一种高效的数据生成方法,该方法可以显著提高数据插入的速度。
在之前的一个项目中,需要生成一个包含1亿3千6百80万条记录的测试表。如果使用传统的数据生成方法,这将需要一个月的时间,因此需要一种更快的数据插入方法。最终,找到了一种新方法,它只需要5小时就能完成数据的生成。
传统的数据生成方法,例如生成从0到100000的数字列表,通常会使用循环和INSERT语句,如下所示:
CREATE TABLE #tempTable(
[Item ID] bigint,
[Item Name] nvarchar(30)
)
DECLARE @counter int
SET @counter = 1
WHILE (@counter < 100000)
BEGIN
INSERT INTO #tempTable VALUES (@counter, 'Hammer')
SET @counter = @counter + 1
END
SELECT * FROM #tempTable
DROP TABLE #tempTable
将这种数据生成方法称为“顺序插入”。
新方法通过复制现有数据并将其作为新数据附加,然后重复此过程,直到生成所需数量的数据。以下是指数插入的代码:
CREATE TABLE #tempTable(
[Item ID] bigint,
[Item Name] nvarchar(30)
)
INSERT INTO #tempTable VALUES (1, 'Hammer')
WHILE ((SELECT COUNT(*) FROM #tempTable) < 100000)
BEGIN
INSERT INTO #tempTable ([Item ID], [Item Name])
SELECT [Item ID] + (SELECT COUNT(*) FROM #tempTable), 'Hammer' FROM #tempTable
END
SELECT * FROM #tempTable
DROP TABLE #tempTable
值得注意的是,WHILE..LOOP的条件是(SELECT COUNT(*))。这个条件语句的评估需要很长时间。一个更快的方法是计算出生成所需记录数(例如,本例中的100000条记录)需要的迭代次数,即2^17=131072,因此可以重写代码,在第17次迭代后停止。
执行从1到100000的数字计数需要4秒;使用以下代码的指数方法只需要2秒:
CREATE TABLE #tempTable(
[Item ID] bigint,
[Item Name] nvarchar(30)
)
INSERT INTO #tempTable VALUES (1, 'Hammer')
DECLARE @counter int
SET @counter = 1
WHILE (@counter <= 17)
BEGIN
INSERT INTO #tempTable ([Item ID], [Item Name])
SELECT [Item ID] + (SELECT COUNT(*) FROM #tempTable), 'Hammer' FROM #tempTable
SET @counter = @counter + 1
END
SELECT * FROM #tempTable
DROP TABLE #tempTable
此外,这种方法不仅可以用于递增数字字段,还可以应用于datetime字段。