在10个表格中同时加载数据

时间:2018-06-24 04:39:50

标签: oracle

我的要求:我有72个oracle表,其中包含数据。很少有表具有数十亿条记录。我需要将数据从72个表直接复制到另一个72个表中。最好的方法是什么?我想一口气将数据复制到5-6张表格中,这样就不应该为了节省时间而一次又一次地加载数据。不知道如何在oracle中实现它。

4 个答案:

答案 0 :(得分:2)

如果数据库表中同时存在源表和目标表,则可以采用以下方法:

a。)使用元数据信息创建配置表以定义规则并为表创建自定义插入语句。 (可选)

b。)用逻辑编写一个过程,将数据从一个表移到另一个表。

c。)在循环中使用DBMS_SCHEDULER编写一个过程,以调度在步骤b)中定义的调用复制过程。调度程序将处理打开和关闭会话的情况。

答案 1 :(得分:1)

我认为您可以使用一些ETL工具。要以不同的方式或表格迁移所有数据。

类似于Pentaho ETL工具。在这里,您可以创建图表并运行它。一切都会好的。 Pentaho也有一个通勤服务器工具。 Pentaho Data Integration or ETL

ETL工具将为您提供提取数据,转换所需内容以及将其加载到任何表或数据库中的机会。

更新

这是ETL工具。据我所知,它适用于Windows和Linux,也许还有MAC。

ETL community tool

答案 2 :(得分:0)

The fastest way to do this will probably be to use the SQL*Plus COPY command。 Oracle誓言要弃用COPY,但考虑到它已被其客户广泛使用,我认为他们会保留一段时间。请注意,如果要同时复制多个表,则必须使用与数据库的多个连接,因为据我所知,没有办法发出不等待复制操作完成之前的COPY命令。让您发出另一个COPY命令。

好运。

答案 3 :(得分:0)

在同一数据库中复制表的最快方法是使用Oracle并行性,而不是并发性。一次并行运行SQL,而不是同时运行多个语句。

在Oracle中,并行性和并发一词的含义略有不同。并行是企业版提供的功能。数据库将创建并行会话以划分和监视工作。并发是指您手动创建和监视同时执行操作的单独进程。

并行性通常比并发容易得多。它通常只需要一个提示就可以启用它(尽管这些简单提示有许多复杂的分支)。并发要求您创建和监视调度程序作业。

并行性通常比并发快得多。 Oracle可能比您可以更好地平均分配工作。并行将工作分解为多个颗粒,并根据需要将它们分配给并行过程。它不是完美的,但通常还不错。将它与并发进行比较,在并发中,您负责查找处理速度相同的X表。找到X个大小相等的表比您想象的要困难得多,而弄错它对于性能来说是毁灭性的。

这是一个将以并行方式加载一组表的过程。您可能需要验证每个语句是否都具有直接路径写和并行性-您可能需要禁用外键,启用NOLOGGING,禁用触发器等。要正确使用它可能要花费几个小时。

create or replace procedure parallel_load
--Purpose: Copy data from source tables to destination tables.
--This procedure truncates target tables - there is no turning back!
(
    p_source_schema in varchar2,
    p_target_schema in varchar2,
    p_tables sys.odcivarchar2list,
    p_dop number
) authid current_user is
    v_sql varchar2(32767);
begin
    --Enable parallel DML for parallel writing.
    execute immediate 'alter session enable parallel dml';

    --Loop through the tables.
    for i in 1 .. p_tables.count loop
        begin
            --Truncate the target table.
            execute immediate 'truncate table '||p_target_schema||'.'||p_tables(i);

            --Create parallel insert.
            v_sql := 
                replace(replace(replace(replace(
                    q'[
                        insert /*+ parallel(#DOP#) */ into #TARGET_SCHEMA#.#TABLE_NAME#
                        select * from #SOURCE_SCHEMA#.#TABLE_NAME#
                    ]'
                , '#DOP#', p_dop)
                , '#TARGET_SCHEMA#', p_target_schema)
                , '#TABLE_NAME#', p_tables(i))
                , '#SOURCE_SCHEMA#', p_source_schema);

            --Execute the parallel insert.
            execute immediate v_sql;

            --Must commit if direct-path writes are used.
            commit;
        exception when others then
            raise_application_error(-20000, 'Error with this SQL: '||v_sql||chr(10)||
                sys.dbms_utility.format_error_stack||sys.dbms_utility.format_error_backtrace);
        end;
    end loop;
end;
/

这是一个调用它的示例。 (找到正确的DOP是很棘手的,尝试使用不同的数字并查看cpu_count中的%parallel%V$PARAMETER参数。)

begin
    parallel_load(
        p_source_schema => 'source_schema',
        p_target_schema => 'target_schema',
        p_tables        => sys.odcivarchar2list('test1', 'test2', 'test3'),
        p_dop           => 8
    );
end;
/

几乎可以肯定,是要使用DBMS_SCHEDULER,ETL程序或COPY命令。这些解决方案比并行处理要复杂得多,速度也要慢得多。 (发布这些答案的人没有违法行为。  在批判评论之前,解释这些表位于同一数据库中。)