Oracle硬解析

Rne*_*net 1 database oracle plsql

我们有一个prepareStatement需要对db做多个操作,所以所有这些sql语句都包含在BEGIN-END块中

BEGIN
 DELETE FROM...WHERE A=?..
 UPDATE TABLE...WHERE B=?..
END;
Run Code Online (Sandbox Code Playgroud)

但许多评论家表示,这将导致一个难以解析的问题.从我的理解硬解析是在共享池中找不到sql,然后语法,执行计划..一切都需要再次计算,但这里不应该将Oracle视为单独的sql语句.我如何才能发现oracle会在给定的sql语句中进行硬解析?

Jon*_*ler 7

绑定变量在PL/SQL块中工作,就像在SQL语句中一样.

您可以通过在循环中运行简单语句来测试它,然后查看解析计数v$sesstat.

创建一个用于插入和删除的简单表.获取初始解析计数.

create table test1(a number);

--Flush the pool, or else this test won't be repeatable.
alter system flush shared_pool;

select value, name
from v$sesstat natural join v$statname
where sid = sys_context('userenv', 'sid')
    and name in ('parse count (total)', 'parse count (hard)');

47  parse count (total)
5   parse count (hard)
Run Code Online (Sandbox Code Playgroud)

这就是硬解析的样子:

begin
    for i in 1 .. 10000 loop
        execute immediate 'insert into test1 values('||i||')';
    end loop;
    commit;
end;
/

select value, name
from v$sesstat natural join v$statname
where sid = sys_context('userenv', 'sid')
    and name in ('parse count (total)', 'parse count (hard)');

10072   parse count (total)
10007   parse count (hard)
Run Code Online (Sandbox Code Playgroud)

带有绑定变量的PL/SQL块并不总是很难解析.请注意,解析计数是累积的,并且它们仅在此处略微增加.

begin
    for i in 1 .. 10000 loop
        execute immediate 
        'begin
            delete from test1 where a = :i;
        end;'
        using i;
    end loop;
    commit;
end;
/

select value, name
from v$sesstat natural join v$statname
where sid = sys_context('userenv', 'sid')
    and name in ('parse count (total)', 'parse count (hard)');

10106   parse count (total)
10019   parse count (hard)
Run Code Online (Sandbox Code Playgroud)