有没有办法从Oracle优化数据迁移到SQL Server,并减少所花费的时间?

问题描述 投票:0回答:2

我从一个Oracle(12C非可插拔)数据库到SQL服务器(2012)使用T-SQL脚本SSMS与Oracle数据库设置为链接服务器迁移数据。该模式已经被同步,所以唯一剩下的东西是数据。我所面临的问题与迁移花费的时间和内存消耗的数量。

当运行我的脚本,它需要很长的时间,最初我完全迁移表时,遇到了内存问题SQL Server的服务器上,所以我决定在同一时间的表迁移到1,000,000行块分割。然而,它好像有一个“内存泄漏”在我的代码查询占用内存与每次迭代增加,查询花费很长的时间。

编辑:我已经在MS SQL服务器数据库中删除索引。

我的剧本作品,但迁移较大的表时,查询将关闭在可用的存储和迁移在开始服用5元左右1分钟磨行(与每次迭代缓慢增加)。当然,时间依赖于行的表中的等量为好。

数据统计:*表:〜1600个*行总数:1〜比尔。 (最大的表为300轧机。行)

USE INFODBA
GO

SET NOCOUNT ON

DECLARE @start BIGINT
DECLARE @end BIGINT
DECLARE @maxrows BIGINT
DECLARE @step BIGINT
DECLARE @sqlstr NVARCHAR(4000)
DECLARE @table_name VARCHAR(255)
DECLARE @counter INT
DECLARE @time TIME
DECLARE @error NVARCHAR(4000)

-- Iterates in @step rows at a time
SET @step = 1000000;
SET @start = 0;
SET @end = @start + @step;
SET @counter = 1;

SET @table_name = 'sourceTable'
PRINT @table_name;

-- GET exact rowcount of Oracle table
SELECT @maxrows = NUM_ROWS FROM OPENQUERY(ORACLETC, 'SELECT COUNT(*) AS NUM_ROWS FROM sourceTable')

WHILE @start < @maxrows
BEGIN
    SELECT @time = CONVERT (time, CURRENT_TIMESTAMP)

    SET @sqlstr = 'INSERT INTO targetTable SELECT * FROM OPENQUERY(ORACLETC,''SELECT COL1,COL2,COL3,COL4 FROM sourceTable'
    SET @sqlstr = @sqlstr + ' OFFSET ' + CAST(@start AS NVARCHAR(255)) + ' ROWS FETCH NEXT ' + CAST(@step AS NVARCHAR(255)) + ' ROWS ONLY'') AS ROWSET_1';

    -- Print output immediatly to capture progress
    PRINT 'Iteration;' + CAST(@counter AS VARCHAR(255)) + ';Time;' + CAST(@time AS VARCHAR(255)) + ';Start;' + CAST(@start AS VARCHAR(255)) + ';End;' + CAST(@end AS VARCHAR(255)) + ';MAX;' + CAST(@maxrows AS VARCHAR(255)) + ';Query;' + @sqlstr
    RAISERROR (N'', 0, 1) WITH NOWAIT

    -- Start the migration query and catch error messages
    BEGIN TRY
        BEGIN TRANSACTION;
            EXEC dbo.sp_executesql @sqlstr
        COMMIT;
    END TRY
    BEGIN CATCH
        SELECT @error = ERROR_MESSAGE();
        PRINT 'ERROR on iteration: ' + CAST(@counter AS VARCHAR(255)) + ' with query: ' + @sqlstr + ' - Error: ' + @error
        SELECT ERROR_MESSAGE() AS ErrorMessage;
        RETURN
    END CATCH

    SET @counter += 1
    SET @start = @end
    SET @end += @step
END

该脚本将迁移的数据集的1个百万行,但现在看来,如果Oracle查询正在按执行计划的时间最多(约80%)。此外,虽然我尝试使用“开始交易”和“承诺”(可能是有使用它一个更好的方法),剧本提到增加了内存占用为每次迭代(大部分的内存被释放提交,但它在后台缓慢增加)

sql-server oracle tsql database-administration data-migration
2个回答
3
投票

有许多方法。

  1. 在SQL Server表中删除索引你的数据导入和导入后重新创建。
  2. 单独的出口,转移和负载。这意味着Oracle服务器以纯文本文件上提取数据,然后通过FTP将其传输到SQL Server计算机,然后将其加载到SQL Server。
  3. (最有效的途径)使用MS SQL Server大容量负荷:https://docs.microsoft.com/en-us/sql/relational-databases/import-export/bulk-import-and-export-of-data-sql-server?view=sql-server-2017在这种情况下,你的记录1米不会通过整个数据库进行处理,而是将被直接写入数据库文件,它的速度更快。

0
投票

弗拉德的答案是正确的;您当前查询包括动态SQL,while循环和OPENQUERY,所有这些都是经常表现猪。使用批量加载(即BCP)或SSIS包导入平面文件应该给你更好的结果。

© www.soinside.com 2019 - 2024. All rights reserved.