我有一个非常大的表(大约1300万行)叫做Book。我想在Book表的一列中设置主键,但由于它是一个非常大的表,服务器在更新期间崩溃。它耗尽内存。所以我创建了一个BookTemp表,我在这个空表中设置了所有主键,然后我想将Book中的数据插入到BookTemp表中。但是,如果我立即这样做,内存再次耗尽。所以我想使用游标来每次插入10,000行然后擦除RAM但我对游标很新,所以在这一点上我希望得到你的帮助。
我使用SQL Server 2008 R2
答案 0 :(得分:1)
我建议使用while循环遍历临时表。示例here应该让您入门。
或者你可以修改一下:
DECLARE @counter AS INT = 0;
DECLARE @batch_size AS INT = 10000;
WHILE (@counter < (SELECT MAX(id) FROM temp_table))
BEGIN
INSERT INTO the_table
SELECT * FROM temp_table
WHERE id BETWEEN @counter AND (@counter + @batch_size - 1);
SET @counter = @counter + @batch_size;
END
答案 1 :(得分:0)
执行以下三个命令后,将通过清理缓存来释放SQL Server的内存。
DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE
但是,它可以用于正在进行的操作,所以请看插入查询,插入每个10000后,通过执行上面的DBCC命令清除内存。
DECLARE @counter INT = 1
DECLARE cur_Data_Transfer CURSOR FOR -- Cursor declared
SELECT column1, column2 -- select desired columns
FROM Book
OPEN cur_Data_Transfer --Opening Cursor
FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2 --Put values to variable
WHILE @@FETCH_STATUS = 0 -- Faching is success
BEGIN
INSERT INTO BookTemp (column1, column2) -- Inserting to temptable
VALUES(@column1, @column2)
IF @counter = 10000
BEGIN
DBCC FREESYSTEMCACHE -- Clear System Cache
DBCC FREEPROCCACHE -- Clear Proc Cache
SET @counter = 0 -- Restarting counter
END
FETCH NEXT FROM cur_Data_Transfer INTO @column1, @column2
SET @counter = @counter + 1
END
CLOSE cur_Data_Transfer -- Closing cursor
DEALLOCATE cur_Data_Transfer -- De-allocating