首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >每当文本更改时,oracle是否会进行硬解析?

每当文本更改时,oracle是否会进行硬解析?
EN

Stack Overflow用户
提问于 2019-11-28 11:28:45
回答 1查看 231关注 0票数 0

我对Oracle中硬解析的理解是,当处理SQL语句时,如果没有找到匹配的文本,就会很难解析。我正在执行一项任务,其中他们从服务中触发多个SQL,如下所示(大约50个变体多次执行)

代码语言:javascript
复制
select * from emp where emp_no in (:V1,:V2);
select * from emp where emp_no in (:V1,:V2,:V3);
select * from emp where emp_no in (:V1,:V2,V3,:V4);

这反过来生成具有相同PHV的多个SQL_ID。我的问题是,这会导致对每条语句的硬解析吗?原因是

time

  • V$SQL/v$SQLSTAS的
  1. AWR报告显示,只有.10秒的.10总运行时间是硬解析的,而解析的.10只显示一小部分时间是硬解析的。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-28 14:26:11

是。

当您向数据库提交语句时,它会散列文本以生成SQL_id。这意味着每个=>都有一个游标,必须有一个硬解析。

您可以通过查询v$sql来验证这一点。这将对每个版本都有一个条目。还可以通过检查parse count (hard) stat来查看硬解析的数量:

代码语言:javascript
复制
var v1 number;
var v2 number;
var v3 number;

alter system flush shared_pool;

select sql_id, executions
from   v$sql
where  sql_text like 'select * from hr.employees%';

no rows selected

select n.display_name, s.value
from   v$mystat s
join   v$statname n
on     s.statistic# = n.statistic#
where  n.name like 'parse count%';

DISPLAY_NAME                 VALUE   
parse count (total)           1682 
parse count (hard)             449 
parse count (failures)           4 
parse count (describe)           0 

select * from hr.employees 
where  employee_id in ( :v1 );
select * from hr.employees 
where  employee_id in ( :v1, :v2 );
select * from hr.employees 
where  employee_id in ( :v1, :v2, :v3 );


select sql_id, executions
from   v$sql
where  sql_text like 'select * from hr.employees%';

SQL_ID              EXECUTIONS   
63dqkasu1w4du                1 
4kr9jqam2p6dw                1 
8gbwr8cry9d84                1 

select n.display_name, s.value
from   v$mystat s
join   v$statname n
on     s.statistic# = n.statistic#
where  n.name like 'parse count%';

DISPLAY_NAME                 VALUE   
parse count (total)           1697 
parse count (hard)             457 
parse count (failures)           4 
parse count (describe)           0 

那么,如果我们再次运行这些语句会发生什么呢?

让我们看看:

代码语言:javascript
复制
select * from hr.employees 
where  employee_id in ( :v1 );
select * from hr.employees 
where  employee_id in ( :v1, :v2 );
select * from hr.employees 
where  employee_id in ( :v1, :v2, :v3 );

select sql_id, executions
from   v$sql
where  sql_text like 'select * from hr.employees%';

SQL_ID              EXECUTIONS   
63dqkasu1w4du                2 
4kr9jqam2p6dw                2 
8gbwr8cry9d84                2 

select n.display_name, s.value
from   v$mystat s
join   v$statname n
on     s.statistic# = n.statistic#
where  n.name like 'parse count%';

DISPLAY_NAME                 VALUE   
parse count (total)           1707 
parse count (hard)             457 
parse count (failures)           4 
parse count (describe)           0 

所以:

  • 每个SQL_id的执行计数增加了1
  • ,硬解析的计数保持不变(457)

=>没有新的硬解析!

这是解释为什么在AWR等中看到如此小的解析值的部分原因。希望您只对每个变体进行一次解析,然后执行很多次,多次执行。

另外,虽然比较昂贵,而且需要避免,但从绝对意义上讲,硬解析仍然是快速的。特别是对于上面这样的简单语句。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59087844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档