Database Oracle硬解析
我们有一个preparedStatement,它需要在db上执行多个操作,因此所有这些sql语句都包含在一个BEGIN-END块中,如Database Oracle硬解析,database,oracle,plsql,Database,Oracle,Plsql,我们有一个preparedStatement,它需要在db上执行多个操作,因此所有这些sql语句都包含在一个BEGIN-END块中,如 BEGIN DELETE FROM...WHERE A=?.. UPDATE TABLE...WHERE B=?.. END; 但许多评论家说,这将导致一个困难的解析。据我所知,硬解析是当在共享池中找不到sql时,语法、执行计划……所有内容都需要重新计算,但Oracle不应将它们视为单独的sql语句。 如何确定oracle是否会对给定的sql语句执行硬解析
BEGIN
DELETE FROM...WHERE A=?..
UPDATE TABLE...WHERE B=?..
END;
但许多评论家说,这将导致一个困难的解析。据我所知,硬解析是当在共享池中找不到sql时,语法、执行计划……所有内容都需要重新计算,但Oracle不应将它们视为单独的sql语句。
如何确定oracle是否会对给定的sql语句执行硬解析?跟踪您的会话并执行代码。运行tkprof并检查解析编号 您是使用绑定变量还是使用文本 建议使用绑定变量,因为当您使用-changing-literals时,这是导致解析发生的因素之一。更改文本确实会降低性能,请使用绑定
下面是一个很好的视频,解释并展示了发生的情况:跟踪您的会话并执行代码。运行tkprof并检查解析编号 您是使用绑定变量还是使用文本 建议使用绑定变量,因为当您使用-changing-literals时,这是导致解析发生的因素之一。更改文本确实会降低性能,请使用绑定
下面是一个很好的视频,解释并展示了发生的情况:绑定变量在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)
绑定变量在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)