请求了SQL调整建议

时间:2019-03-27 23:43:40

标签: sql oracle plsql

我有一些PL / SQL,它可以运行并“运行”,我想知道是否可以以更有效的方式编写它?

在某些背景下,元数据表包含可用于构造在远程数据库上执行的查询的信息。 这被传递到“ c1”。 “ driver_table”用于限制返回的数据,我们不需要所有数据,因此查询中存在一些条件。 例如,它可以是LIMITER_USER.TABLE1,mand_join是一个连接条件,例如A.ID = B.ID add_joins是where子句。例如。 B.DTE> = '01 -DEC-2014' 因此,最终,PL / SQL在循环中构造许多SQL并将其输出到输出中。

declare
v_sql_c1 pls_integer;
l_dblink varchar2(100) := 'DB1';

begin

for c1 in (select /*+parallel*/ * from meta_data_tbl where add_joins is not null)
loop
execute immediate' select /*+parallel*/ count(*) from '||c1.schema||'.'||c1.table|| '@' ||l_dblink ||' b '
||','||
c1.driver_table 
|| '@' ||l_dblink ||' a '
||' where '||
c1.mand_join
||' and '||
c1.add_joins
into v_sql_c1;
dbms_output.put_line(v_sql_c1);
end loop;
end;
/

我希望输出尽可能地高效(如果还没有的话)。目前需要十二分钟才能完成

1 个答案:

答案 0 :(得分:1)

您可能希望使用并行管道功能来启用并发和并行性。

术语“并发”和“并行性”通常是同义词,但在Oracle中有时具有不同的含义。并发是指同时运行多个SQL语句或PL / SQL块,而并行是指一个SQL语句具有多个线程的运行。

您当前的程序使用并行性来获取游标数据,但这不会使游标FOR循环在多个线程中运行。由于您正在使用数据库链接,因此我假设这些语句将在许多数据库上运行,因此您可以通过在多个数据库上同时运行它们来节省时间。

并行流水线函数并行运行输入游标,并对结果进行分区并在多个线程中运行它们。 (您可以使用DBMS_SCHEDULER实现相同的操作,但是该解决方案需要更多的管理代码。)

--Create parallel pipelined function.
create or replace function parallel_pipe(p_cursor sys_refcursor)
return sys.odcinumberlist pipelined
parallel_enable(partition p_cursor by any) is
    v_meta_data_tbl meta_data_tbl%rowtype;
    v_sql varchar2(32767);
    v_count number;
begin
    loop
        fetch p_cursor into v_meta_data_tbl;
        exit when p_cursor%notfound;

        v_sql := 'select /*+ parallel */ count(*) from '||
            v_meta_data_tbl.schema||'.'||v_meta_data_tbl.table_name;

        execute immediate v_sql into v_count;

        pipe row(v_count);
    end loop;
end;
/

--Call the function.
select column_value row_count
from table(parallel_pipe(cursor(select /*+ parallel */ * from meta_data_tbl)));

我没有重新创建整个表并加入。我只是使用了足够小的模式来说明原理:

create table meta_data_tbl(schema varchar2(128), table_name varchar2(128));
insert into meta_data_tbl select 'SYS', 'DUAL' from dual connect by level <= 100;
commit;

在合并并发和并行性时要小心。上述解决方案可能会使您的服务器工作难度提高几个数量级。您应该尝试使用不同的组合-尝试仅运行并发,或者并发或少量并行运行,等等。