简体   繁体   English

PL/SQL 匿名块中的查询执行速度很慢

[英]Query execution is slow in PL/SQL anonymous block

The query runs slow in Oracle PL/SQL.查询在 Oracle PL/SQL 中运行缓慢。 It takes about 8 minutes in PL/SQL whereas it takes only 4 seconds when run in SQL Editor or SQL Plus.在 PL/SQL 中大约需要 8 分钟,而在 SQL Editor 或 SQL Plus 中运行时只需 4 秒。

Please let me know what is causing this.请让我知道是什么原因造成的。 Is it possible that a different execution plan is picked up by SQL and PL/SQL? SQL 和 PL/SQL 是否有可能选择不同的执行计划?

----SQL Editor query---takes 4 seconds---400 row count--
SELECT count(*) FROM
(
SELECT col1, col2
FROM
my_tab1 t1, my_tab2 t2
WHERE
t1.pk_col1=t2.pk_col1
and t1.created_date < t2.created_date
)


--PL/SQL Code--takes about 8 minutes---400 row rount--
DECLARE 
v_cnt   PLS_INTEGER:=0;
BEGIN
SELECT count(*) INTO v_cnt 
FROM
(
SELECT col1, col2
FROM
my_tab1 t1, my_tab2 t2
WHERE
t1.pk_col1=t2.pk_col1
and t1.created_date < t2.created_date
)

END;
/

The easiest way to capture the execution plan within an anonymous block is to call dbms_xplan.display_cursor in a loop and print each line of output:在匿名块中捕获执行计划的最简单方法是在循环中调用dbms_xplan.display_cursor并打印 output 的每一行:

declare
    v_cnt pls_integer;
begin
    execute immediate 'alter session set statistics_level = ALL';

    select count(*) into v_cnt 
    from
    (
        select col1, col2
        from   my_tab1 t1, my_tab2 t2
        where  t1.pk_col1 = t2.pk_col1
        and    t1.created_date < t2.created_date
    );

    for r in (
        select p.plan_table_output
        from   table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST -OUTLINE +NOTE +PREDICATE +IOSTATS +REPORT')) p
    )
    loop
        dbms_output.put_line(r.plan_table_output);
    end loop;
end;

You can make the same call from a SQL*Plus command prompt immediately after executing a SQL statement, but you first have to disable dbms_output, as otherwise the SQL statement is not the 'last' statement you made.您可以在执行 SQL 语句后立即从 SQL*Plus 命令提示符进行相同的调用,但您首先必须禁用 dbms_output,否则 SQL 语句不是您所做的“最后”语句。 (You can also specify the sql_id if you know it.) For more details see the dbms_xplan documentation . (如果您知道,也可以指定 sql_id。)有关详细信息,请参阅dbms_xplan 文档

set serverout off

alter session set statistics_level = ALL;

select count(*)
from
(
    select col1, col2
    from   my_tab1 t1, my_tab2 t2
    where  t1.pk_col1 = t2.pk_col1
    and    t1.created_date < t2.created_date
);

select p.plan_table_output
from   table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST +OUTLINE +ADAPTIVE +PARTITION +NOTE')) p;

For a handy script to call this in one line, see www.williamrobertson.net/documents/xplanx.html .有关在一行中调用它的便捷脚本,请参阅www.williamrobertson.net/documents/xplanx.html Then it's just那么就只是

select count(*)
from
(
    select col1, col2
    from   my_tab1 t1, my_tab2 t2
    where  t1.pk_col1 = t2.pk_col1
    and    t1.created_date < t2.created_date
)

@xplanx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM