【问题标题】:faster way for moving large amounts data in oracle to external database将oracle中的大量数据移动到外部数据库的更快方法
【发布时间】:2011-08-18 16:09:50
【问题描述】:

我有一个 java 程序,它比较本地 Oracle 数据库中的数据并将其移动到由在线供应商托管的外部 MS SQL 数据库。

目前,该程序连接到 MS SQL 数据库,执行 SELECT * FROM myTABLE 并将结果放入二维数组中。然后在 Oracle 中创建一个临时表,并使用 for 循环将数据插入到临时表中:

for (int ii = 0; ii < arr.length(); ii++){
    query = "insert into myTable_temp values "+values_from_array;
    stmt.executeQuery();
} 

使用MINUS 语句查找差异:

query = "select * from ora_table minus select * from myTable_temp";
rs = stmt.executeQuery();

然后使用 insert_into_mssql() 方法将结果插入回 MS SQL 表中:

while (rs.next()){
    query = "insert into myTable values "+ values_from_rs
    insert_into_mssql(query);
}

除了我使用的表有 220,000 行之外,这很好用。因此加载数组、插入临时表、运行减号语句、然后将所有内容重新插入 mssql 表需要很长时间。

有没有更有效的方法来做到这一点?或者让这个更快的方法? (由于安全限制,dblink 或任何直接连接都不起作用)

【问题讨论】:

  • 您的组织真的考虑过这些安全限制吗?数据库链接只需要一组额外的权限,并加密您的密码。您是否为这个 Java 程序在不同的服务器上创建了一个额外的帐户,并授予它对两个数据库的权限?密码是否加密?

标签: java sql-server oracle


【解决方案1】:

是的,您使用的是什么版本的 MS SQL Server?根据这一点,您可以查看SSIS 或其他DTS 软件。它可以让您非常快速地做您想做的事。

【讨论】:

    【解决方案2】:

    我认为创建dblink 是个好主意。

    【讨论】:

      【解决方案3】:

      也许对你有帮助。

      Statement 的新 addBatch( ) 方法允许您将多个更新语句合并为一个单元并一次执行它们。在创建语句之后、执行之前调用 addBatch():

      con.setAutoCommit(false); // If some fail, we want to rollback the rest
      Statement stmt = con.createStatement(  );
      
      stmt.addBatch(
      "INSERT INTO CUSTOMERS VALUES (1, "J Smith", "617 555-1323");
      stmt.addBatch(
      "INSERT INTO CUSTOMERS VALUES (2, "A Smith", "617 555-1132");
      stmt.addBatch(
      "INSERT INTO CUSTOMERS VALUES (3, "C Smith", "617 555-1238");
      stmt.addBatch(
      "INSERT INTO CUSTOMERS VALUES (4, "K Smith", "617 555-7823");
      
      int[] upCounts = stmt.executeBatch(  );
      con.commit(  );
      

      请注意,我们在创建批处理之前关闭了事务自动提交。

      【讨论】:

        【解决方案4】:

        我可能会先不将它加载到数组中,而只是使用与您在写出时使用的类似技术。还可以考虑并行化插入。

        如果我从头开始执行此操作,我会将所有 Oracle 数据带到 SQL Server 并在那里执行所有操作(从 Oracle 复制表,查找差异并插入 SQL Server,删除从 Oracle 复制的表),而不是将所有SQL Server 数据到 Oracle,只转储新记录并将它们带到 SQL Server 并插入它们。

        SQL Server 也有一个相当不错的 ETL 工具 - SQL Server Integration Services,但除了 SQL Server 数据源和目标之外,我还没有成功使用它。

        【讨论】:

        • 我使用 SSIS 将数据从 Oracle 数据库迁移到 SQL Server 数据库没有任何问题。实际上,当涉及到源和目标时,SSIS 几乎可以处理任何东西(DB、Excel 文件、平面文件,你可以命名它)
        • @Cade Roux 您如何将所有 Oracle 数据带到 SQL Server?
        • @Mike 您可以像现在更改记录一样执行此操作,但我会使用 SSIS。
        • @AJC 我在使用 Teradata 时遇到了问题。 Excel 和 Access 在 64 位环境中存在问题。但是,是的,它通常非常棒。
        • @Mike SSIS 允许您连接到任何源、提取数据、对其进行转换,然后将其加载到任何目的地,从而实现 ETL。
        【解决方案5】:

        考虑到技术限制(无 dblink 等),您可以尝试降低传输开销。 这可以通过保持同步状态并仅传输更新的行来完成。

        如果我理解正确,您只需将更新的和新的行从 Oracle 数据库传输到 MS SQL。在非常通用的变体中,您需要将 2 列添加到保存复制状态的 oracle_table 中:

        last_update_time - 在插入或更新每一行时由触发器维护。触发器将列值设置为每行更改和新行的当前日期和时间。

        last_sync_time - 在插入时由触发器维护并由同步应用程序更改。

        对于新行 last_update_time := sysdatelast_sync_time := last_update_time - 1

        在每个oracle_table 行更新last_update_time 按当前日期时间更新。

        在每个同步会话上执行下一个序列:

        1. oracle_table 中选择所有行,其中last_sync_time &lt; last_update_time 并将其插入到Oracle 服务器上的某个缓冲区表中:

          begin
            execute immediate 'truncate table buffer_table';
          
            insert into buffer_table(...)
            select * from oracle_table where last_sync_time < last_update_time;
          
          end;
          
        2. 将所有行从 buffer_table 传输到 MS SQL 服务器并相应地更新 myTable

        3. 将所有同步行的更新时间提前到新值:

          update 
            oracle_table o_table
          set 
            last_sync_time = ( select buf_table.last_update_time 
                               from buffer_table buf_table
                               where buf_table.Primary_Key = o_table.Primary_Key
                             )
          where
            o_table.Primary_Key in (select Primary_Key from buffer_table)
          

        请注意,同步的行可能会在同步过程中发生变化,我们在更新 last_sync_time 时需要来自 buffer_table 的时间戳值。

        附注我认为 MS SQL 端的数据库是只读的。双向同步可以在相同的原理下完成,只需稍微改进一下算法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-22
          • 2012-03-07
          • 2020-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多