Oracle SQL脚本并行执行

niwlg2el  于 2023-01-30  发布在  Oracle
关注(0)|答案(2)|浏览(210)

我的工作需要准备两张table(CTAS),然后在它们之间执行一些连接。(在SQL Developer中运行),这将依次创建这两个表。由于这两个表不相关,我希望开始并行创建它们。是否可以在SQL脚本中开始创建两个表(或其他两个脚本),然后在两个脚本都完成工作后继续?

zmeyuzjn

zmeyuzjn1#

有一个选择。
我不会真的使用CTAS --我宁愿 * 提前 * 创建两个表,然后在其中插入行。为什么?因为这种方法使用存储过程--为了执行DDL(也就是CTAS)--需要动态SQL。并不是说这是 * 不可能 * 做到的;相反,但不使用它要简单得多。
我还要创建另一个表(我们称之为table_done),它只包含一行两列:table_1table_2,其值可以是0(表示:该表的数据未就绪)或1(数据就绪)。
此外,我将创建两个看起来相同的存储过程;唯一的区别是它们中的每一个都将行插入到自己的表中:

create procedure p_insert_1 as
begin
  -- remove old data
  execute immediate 'truncate table table_1';

  -- table_1 data not ready
  update table_done set table_1 = 0;

  -- prepare new data
  insert into table_1 (...) select ...;

  -- table_1 data ready
  insert into table_done (table_1) values (1);
  commit;
end;

第三个“main”过程是您要 * 手动 * 运行的过程。它会做什么?创建两个 * 立即 * 运行的一次性数据库作业,每个作业都启动自己的p_insert过程,以便并行运行。然后,该过程将(在循环中)检查table_done中的两列是否都设置为1,如果是,则继续执行。

create procedure p_main is
  l_job_1 number;
  l_job_2 number;
  --
  l_t1_done number;
  l_t2_done number;
begin
  dbms_job.submit(l_job_1, 'begin p_insert_1; end;');
  dbms_job.submit(l_job_2, 'begin p_insert_2; end;');

  loop
    select table_1, table_2
      into l_t1_done, l_t2_done
      from table_done;

    if l_t1_done = 1 and l_t2_done = 1 then
       -- exit the loop
       exit;
    else 
       -- tables aren't ready yet; wait 60 seconds and try again
       dbms_lock.sleep(60);
    end if;
  end loop;

  -- process data prepared in table_1 and table_2
end;

这只是一个简单的想法我没有亲自测试,所以如果有任何错误,我道歉。另外,

  • 您可以选择使用 * 高级 * dbms_scheduler而不是dbms_job
  • 如果您使用的是18 c(或更新版本),请使用dbms_session.sleep而不是dbms_lock.sleep
  • 等等
yuvru6vn

yuvru6vn2#

使用 *SQL并行性 * 而不是 * 进程并发性 *。虽然并行性和并发性这两个词在口语中可以互换,但在Oracle中它们有不同的含义。并行性意味着SQL引擎处理所有的协调工作,包括将工作分解为多个小块,同时运行这些小块,然后在最后重新组合结果。并发意味着用户将创建多个会话并手动处理协调。
对于简单地创建两个表,并行可能比并发更简单、更快。对于并行,您可能只需要并行地创建表。(并且您可能希望在最后将并行重置为无。)

CREATE TABLE TABLE1 PARALLEL 2 AS SELECT ...;
ALTER TABLE TABLE1 NOPARALLEL;

PARALLEL 2选项指示Oracle在SQL语句运行时同时运行两个服务器进程。您可以轻松地增加该数目,但不要设置得太高,否则将从其他会话窃取太多资源。
DBMS_SCHEDULER和其他并发机制非常强大和有用,但我建议尽可能避免使用它们。运行和监视调度程序作业可能比前面的代码复杂得多。(尽管您可能仍然需要偶尔使用OEM SQL Monitor Reports之类的工具监视并行SQL语句,以确保服务器实际上正在使用所请求的并行性。)

相关问题