Oracle 硬解析

Posted

技术标签:

【中文标题】Oracle 硬解析【英文标题】:Oracle hard parse 【发布时间】:2012-04-20 04:08:01 【问题描述】:

我们有一个preparedStatement,它需要对数据库执行多个操作,因此所有这些sql 语句都包含在一个BEGIN-END 块中,例如

BEGIN
 DELETE FROM...WHERE A=?..
 UPDATE TABLE...WHERE B=?..
END;

但许多评论者表示这将导致难以解析。根据我的理解,硬解析是当在共享池中找不到 sql 时,语法、执行计划 .. 一切都需要重新计算,但这里不应该 Oracle 将它们视为单独的 sql 语句。 如何确定 oracle 是否会对给定的 sql 语句进行硬解析?

【问题讨论】:

【参考方案1】:

绑定变量在 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)

这就是硬解析的样子:

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)

带有绑定变量的 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)

【讨论】:

【参考方案2】:

跟踪您的会话执行代码。运行 tkprof 并检查解析数。

你使用绑定变量还是使用文字?

建议使用绑定变量,因为当您使用 - 更改 - 文字时,这是导致解析发生的因素之一。更改文字确实会降低您的性能,请使用绑定。

这是一个很好的视频,解释并展示了发生的事情:OLTP Performance - The Trouble with Parsing

【讨论】:

以上是关于Oracle 硬解析的主要内容,如果未能解决你的问题,请参考以下文章

[ORACLE]oracle SQL执行过程 软解析(soft prase)硬解析(hard prase)以及 Soft Soft Parse

查询软解析,硬解析百分比

几种常见重新硬解析的原因

oracle中关于替代变量,accpt,绑定变量,字符变量

Oracle绑定变量

Oracle DB 12.2(12cR2)的一个新特性:硬解析失败的SQL语句(需要符合一定条件)打印到alert_sid.log中.