SQL 服务器使用 INSERT INTO 加速 WHILE 循环

SQL Server speed up WHILE Loop with INSERT INTO

SQL WHILE Loop is Slow with Insert Into。 有什么办法可以加快查询速度吗?

我想插入 500,000 行。如果每 10,000 行之后有一个提交,它会更快吗?

示例:

将行从 DB1 插入到 DB2,并从 DB2 获取主自增键 ID 到 DB1。

CREATE TABLE #TempTable
    (
        ROWID int identity(1,1) primary key,
        Comp_Key_1 NVARCHAR(20),
        Comp_Key_2 NVARCHAR(256),
        Comp_Key_3 NVARCHAR(256)
    )
INSERT INTO #TempTable (Comp_Key_1, Comp_Key_2, Comp_Key_3) 
SELECT Comp_Key_1, Comp_Key_2, Comp_Key_3 FROM [DB1].[dbo].FILES


DECLARE @MAXID INT, @Counter INT, @Comp_Key_1 NCHAR(20), @Comp_Key_2 nvarchar(256), @Comp_Key_3 nvarchar(256), @id_current int,;
SET @COUNTER = 1
SELECT @MAXID = COUNT(*) FROM #Temp

WHILE (@COUNTER <= @MAXID)
        BEGIN

            set @Comp_Key_1= (select Comp_Key_1_doc from #Temp where ROWID= @COUNTER)
            set @Comp_Key_2= (select Comp_Key_2_doc from #Temp where ROWID= @COUNTER)
            set @Comp_Key_3= (select Comp_Key_3_doc from #Temp where ROWID= @COUNTER)

            INSERT INTO [DB2].[dbo].[ADDRESS] (STREET,STREET_FROM,STREET_TO)
            SELECT STREET,STREET_FROM,STREET_TO
            FROM [DB1].[dbo].[ADDRESS]
            WHERE [DB1].[dbo].[ADDRESS].Comp_Key_1= @Comp_Key_1
               and [DB1].[dbo].[ADDRESS].Comp_Key_2=@Comp_Key_2
               and [DB1].[dbo].[ADDRESS].Comp_Key_3=@Comp_Key_3;

            set @id_current = IDENT_CURRENT('[DB2].[dbo].[ADDRESS]')

            update [DB1].[dbo].[ADDRESS]
            set id=@id_current
            where @Comp_Key_1=[ADDRESS].Comp_Key_1
              and @Comp_Key_2=[ADDRESS].Comp_Key_2
              and @Comp_Key_3=[ADDRESS].Comp_Key_3;

        SET @COUNTER = @COUNTER + 1


      END 
    COMMIT

DB2 有一个自增主键,希望在每插入一行后在DB1 中传输。 DB1 有一个 3 列的组合键。 DB2 的设计不包括组合键。

example of the tables

有什么方法可以加快插入速度吗?

感谢您的帮助!

我按照建议使用了带有 OUTPUT 子句的 MERGE 语句,将生成的 ID 和初始组合键插入临时 table 以便稍后通过加入进行更新。

非常高效(只用了 15 分钟)而且不需要循环。谢谢!

这是代码:

BEGIN TRAN
CREATE TABLE #TempInserted
    (inserted_id int,Comp_Key_1 NVARCHAR(20), Comp_Key_2 NVARCHAR(256), Comp_Key_3 NVARCHAR(256))

MERGE [DB2].[dbo].[ADDRESS] AS T  -- target table T
USING (SELECT STREET,STREET_FROM,STREET_TO, Comp_Key_1,Comp_Key_2, Comp_Key_3
       FROM [DB1].[dbo].[ADDRESS] AS M ) S  -- source table S
ON 0=1
WHEN NOT MATCHED THEN
    INSERT (STREET,STREET_FROM,STREET_TO) -- target table T
    VALUES (STREET,STREET_FROM,STREET_TO) -- source table S

OUTPUT inserted.id, S.Comp_Key_1, S.Comp_Key_2, S.Comp_Key_3 
INTO #TempInserted(inserted_id,Comp_Key_1,Comp_Key_2,Comp_Key_3);

update [DB1].[dbo].[ADDRESS]
set id=#TempInserted.inserted_id 
FROM [BankMasterDB_migration].[dbo].LOANNUMBER AS M
JOIN #TempInserted ON M.Comp_Key_1=#TempInserted.Comp_Key_1
                  AND M.Comp_Key_2=#TempInserted.Comp_Key_2
                  AND M.Comp_Key_3=#TempInserted.Comp_Key_3

COMMIT