Самый быстрый способ обновления строк в большой таблице в SQL Server - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть одно сомнение в SQL Server В основном мне нужно выполнить это для таблицы с 60 миллионами строк, обновление каждой строки за один раз приведет к сбою, поэтому я хочу выполнить пакетный запрос, чтобы в случае сбоя он мог повторно выполнить запрос и пропустить завершенный пакет и просто продолжайте с оставшимися.

Мне нужны обновленные данные таблицы emp со ссылкой на таблицу empref. Здесь в обеих таблицах содержатся миллионы записей, но я приведу некоторые примеры данных ниже.

в то время как время обновления нам нужно разделить пакеты с предложением top и не должно повторять существующее top.

образцы таблиц с данными:

CREATE TABLE [dbo].[emp](
    [id] [int] NULL,
    [name] [varchar](50) NULL,
    [sal] [int] NULL
) 
CREATE TABLE [dbo].[empref](
    [id] [int] NULL,
    [name] [varchar](50) NULL,
    [sal] [int] NULL
) 
INSERT [dbo].[emp] ([id], [name], [sal]) VALUES (1, N'a', 100)
GO
INSERT [dbo].[emp] ([id], [name], [sal]) VALUES (2, N'b', 200)
GO
INSERT [dbo].[emp] ([id], [name], [sal]) VALUES (4, N'u', 300)
GO
INSERT [dbo].[emp] ([id], [name], [sal]) VALUES (7, N'x', 400)
GO
INSERT [dbo].[emp] ([id], [name], [sal]) VALUES (8, N't', 500)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (1, N'xx', 100)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (2, N'bb', 200)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (4, N'uu', 300)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (7, N'xxx', 400)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (8, N'tt', 500)
GO
INSERT [dbo].[empref] ([id], [name], [sal]) VALUES (10, N'ub', 600)
GO

на основе приведенных выше данных, я хочу вывод, как показано ниже:

emp:
id  |name|sal
1   |xx |100
2   |bb |200
4   |uu |300
7   |xxx|400
8   |tt |500

Я попробовал, как показано ниже:

declare @i int
 set @i=1

 while ( @i <= (select max(id) from emp ))

 begin 
 update  TOP(2)  t  set t.name=s.name 
 from emp t join empref s  on t.id=s.id 
 print @@rowcount

 set @i=@i+1
 end 

вышеуказанный запрос на обновление обновляется только в том случае, если только две верхние записи не обрабатываются, и следующий запрос на обновление двух верхних записей не повторяется. всегда обновляются только те топ-2 записи.

скажите, пожалуйста, как создать несколько пакетов, используя цикл while на сервере sql.

1 Ответ

0 голосов
/ 17 сентября 2018

Не могу сказать, что это будет самый быстрый подход, но причина, по которой WHILE LOOP выбирает те же две строки, заключается в том, что вам также необходимо отслеживать столбец Id в таблице Emp

Предполагая, что столбец Id является столбцом Identity без пробелов

DECLARE @i  INT, @TrackId INT
SET @i = 1;
SET @TrackId = (SELECT  MIN(Id) FROM emp)
SELECT @TrackId

WHILE (@i <= (SELECT MAX(Id) FROM emp))
BEGIN
    DECLARE @tempEmp TABLE ( Id INT, [name] VARCHAR(50))
    INSERT INTO @tempEmp
    (Id ,[name] )
    SELECT TOP 2 E.Id, [E].[name]
    FROM dbo.emp E
    WHERE E.Id >= @TrackId
    ORDER BY E.Id ASC

    UPDATE 
        t
    SET t.[name] = s.[name]
    FROM dbo.emp t
    JOIN @tempEmp TE ON TE.Id = t.id
    JOIN empref s ON t.Id   = s.Id

    PRINT @@ROWCOUNT;

    SET @TrackId = (SELECT  MAX(Id) FROM @tempEmp)

    SET @i = @i + 1;
END;
...