我在SQL Server 2014中运行SQL语句。 我有3列:id,text1,text2 在text1,text2中插入记录 text1是nvarchar text2是varchar 到目前为止,在大约3.5小时内插入了120万行 试图插入300万需要帮助以减少插入时间
CODE:
DECLARE @i as int
SET @i = 0
WHILE @i < 3000000
BEGIN
SET @i = @i + 1
insert into test (text1 , text2)
values(N'你好','VJ'+ cast(@i as varchar(20)))
END
答案 0 :(得分:1)
您可以尝试这样
WITH CTE_TEST
AS
(
SELECT N'你好' AS CODE,'VJ'+ cast(1 as varchar(20)) NAME, 1 AS VCOUNT
UNION ALL
SELECT N'你好' ,'VJ'+ cast(VCOUNT+1 as varchar(20)) NAME, VCOUNT+1 AS VCOUNT
FROM CTE_TEST
WHERE VCOUNT+1 < 3000000
)
INSERT INTO test (text1 , text2)
SELECT CODE,NAME FROM CTE_TEST
OPTION (MAXRECURSION 0)
您可以在CTE中使用其他逻辑,只需将结果集插入实际表中即可。这里的insert语句在循环之外(带有3000000条记录的1个insert语句),因此它比在3000000次循环中插入记录要快得多(3000000个insert语句,每条记录1条记录)
默认情况下,MAXRECURSION为100以避免无限循环,在这里你需要覆盖它(但这不是一个好习惯)。
答案 1 :(得分:1)
不使用递归CTE的替代方法是使用具有足够记录的已知表,以便您可以对其进行迭代:
-- generation parameters
declare @batchCount INT = 100000
declare @totalCount INT = 30000000
declare @loopCount INT = @totalCount / @batchCount
DECLARE @i as int = 0
-- loops are slow, but here we have only a few
WHILE (@i < @loopCount)
BEGIN
-- insert can be put just here to actually perform the insert
-- ROW_NUMBER gives us the numbering, but order does not matter, so using SELECT 1
select TOP (@batchCount) N'你好','VJ'+ cast(@i * @batchCount + ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as varchar(20))
from sys.messages
SET @i = @i + 1
END
sys.messages
是一个非常大的表(至少200K
条记录),因此它可以安全地用于100K
批次。
使用recursive CTE
的时间:51s
使用上述解决方案的时间:28s
(在SQL Server 2014 Express
个实例上测试,仅限SELECT
)
答案 2 :(得分:1)
这是另一种方法...它完成得非常快......在我的SQL服务器上不到5秒
if object_id('tempdb..#Numbers') is not null drop table #Numbers
create table #Numbers (Num int)
insert into #Numbers (Num)
SELECT TOP (3000000) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);
if object_id('tempdb..#test') is not null drop table #test
create table #test (text1 nvarchar(50), text2 nvarchar(50))
insert into #test (text1, text2)
select N'你好' [text1], 'VJ' + cast(Num as nvarchar) [text2] from #Numbers