`
Fred_Han
  • 浏览: 148135 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

查看硬解析次数

 
阅读更多

TOM大叔的调优书中说过一句话,具体英文就忘了,大概意思就是:如果有人让我写本怎样让ORACLE性能最慢的书的话我会将取消绑定变量(bind variable)做为书的第一章和最后一章(他的意思是他很有幽默~~!),可见绑定变量的重要性。
绑定变量大多用在OLTP(online transaction process)中,在OLAP(online analizy process)中就没必要用BIND VARIABLE了。
要了解绑定变量的作用首先得了解下SHARED_POOL library cache中的SQL解析。
SQL 解析分为硬解析(hard parse)跟软解析(soft parse)。所谓硬解析就是真正的将产生的SQL用自己内部的算法完全解析一遍并将解析后的结果存入库缓存(library cache),而软解析就是发现库缓存中已经存在解析过的该SQL语句,从而直接利用,跳过重新解析的步骤。
所以SQL解析的步骤就是:先判断库缓存中是否存在该sql的解析,存在就不用再解析(软解析),没有就解析一遍(硬解析),并存入库缓存。
下面做个实验:

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        276 143509059

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        276 143509059
--这里value记录的就是硬解析次数,上面这个select语句同样第一次会被解析,之后就软解析了。

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        281 143509059
-- 过会再执行此句,可以看到这里VALUE变成281了,有人可能会有疑问,不是276的吗,怎么变了?原因是库内部平时也在做各种操作,比如状态收集等, 可能会产生硬解析,而且执行一段时间之后,ORACLE会根据最近最少使用原则将此SQL解析踢出共享池,再执行就要重新解析一遍了。

--为了尽量不影响我们的分析,将库以只读启动:
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup mount
ORACLE 例程已经启动。

Total System Global Area 167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              62915940 bytes
Database Buffers          100663296 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。
SQL> alter database open read only
2 ;

数据库已更改。

SQL> col name for a20
SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        188 143509059

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        188 143509059

SQL> select * from t where id=2009;

        ID
----------
      2009

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        190 143509059
--解析id=2009的查询
SQL> select * from t where id=2009;

        ID
----------
      2009

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        190 143509059
--此前解析过,所以再此查询2009时VALUE不变,软解析。
SQL> select * from t where id= 2009;

        ID
----------
      2009

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        191 143509059
--此处注意,2009前面有个空格,也会被判断为跟原来的SQL不匹配。
SQL> select * from t where Id=2009;

        ID
----------
      2009

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        192 143509059
--此处的Id的I是大写,也会跟原来的查询不匹配,所以硬解析。
SQL> select * from t where id=2010;

        ID
----------
      2010

SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64        194 143509059
--2010跟2009的查询SQL解析不共享,所以也要硬解析。
SQL> show parameter cursor_sharing

NAME                                 TYPE                   VALUE
------------------------------------ ---------------------- ---------
cursor_sharing                       string                 EXACT
此外,cursor_sharing参数也会影响ORACLE判断SQL是否共享,此处用的是EXACT,也是10G默认的,11G中已不是。以后我会单独讨论下这个参数。

可以想象,如果对10W个不同的ID每个都查询一次,硬解析的次数是很大的,会导致性能的下降。而用绑定变量来代替ID的值,10W条数据的查询会被共享为一条SQL,只硬解析一次,带来的性能提升也是很明显的。
下面也对绑定变量做个实验,向T表插入10W条数据。可以看出用绑定变量跟不用的巨大差异。

SQL> set timing on
SQL> truncate table t;

Table truncated.

Elapsed: 00:00:00.04
--p1不用绑定变量
SQL> create or replace procedure p1
2 as
3 begin
4 for i in 1..100000 loop
5 execute immediate 'insert into t values('||i||')';
6 end loop;
7 end;
8 /

Procedure created.

Elapsed: 00:00:00.06
--p2用绑定变量
SQL> create or replace procedure p2
2 as
3 begin
4 for i in 1..100000 loop
5 execute immediate 'insert into t values(:a)' using i;
6 end loop;
7 end;
8 /

Procedure created.

Elapsed: 00:00:00.04
SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64     143800 143509059

1 row selected.

Elapsed: 00:00:00.01
SQL> exec p1;

PL/SQL procedure successfully completed.

Elapsed: 00:01:10.01
SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64     243800 143509059

1 row selected.

Elapsed: 00:00:00.01
SQL> truncate table t;

Table truncated.

Elapsed: 00:00:00.12
SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64     243801 143509059

1 row selected.

Elapsed: 00:00:00.03
SQL> exec p2;

PL/SQL procedure successfully completed.

Elapsed: 00:00:14.67
SQL> select * from v$sysstat where statistic#=331;

STATISTIC# NAME                      CLASS      VALUE    STAT_ID
---------- -------------------- ---------- ---------- ----------
       331 parse count (hard)           64     243803 143509059

1 row selected.

Elapsed: 00:00:00.00

可见差异之大。。
做 实验的时候发现过程p2中用insert into t values(i)代替execute immediate 'insert into t values(:a)' using i的话,消耗的时间是相近的,也就是说前者也会被替换成使用绑定变量的方式。感兴趣的朋友可以试一下。不足的地方欢迎指正~

转自:http://hi.baidu.com/kywinder/item/8dc7972656a6019db7326341

分享到:
评论

相关推荐

    ORACLE 查看相关的sql语句是否会增加硬解析次数

    ORACLE有些sql语句,不确定它是否会增加硬解析次数,对其它进行测试,是否会增加硬解析。

    oracle-查找硬解析问题SQL语句

    在数据库中硬解析是万恶之源,为大家提供一个查找并且定位oracle硬解析问题SQL语句脚本

    Oracle中的硬解析与软解析

    软解析是 Oracle 数据库中的一种优化机制,它可以减少硬解析的次数,提高系统的整体性能。 Oracle 数据库提供了 shared_pool_size 参数来缓存 SQL 语句,以便重用已经解析的 SQL 语句。然而,如果 shared_pool_...

    Oracle硬解析和软解析的区别分析

    如果发现硬解析次数过高,可能需要对SQL语句进行优化,或者调整数据库的配置,以确保系统的高效运行。 总之,Oracle的硬解析和软解析是数据库解析策略的两个关键方面。理解它们的工作原理,并能有效地控制和优化,...

    【Oracle性能调优】OracleStatspack报告中各项指标含义详解[归类].pdf

    每事务硬解析次数是指每事务产生的硬解析次数。 30. Sorts/Sec(每秒排序次数) 每秒排序次数是指每秒产生的排序次数。 31. Sorts/Tx(每事务排序次数) 每事务排序次数是指每事务产生的排序次数。 32. ...

    Oracle动态性能表.doc

    6. parse count (hard): 表示在shared pool中因未命中而导致的硬解析次数。硬解析会导致额外的CPU和资源消耗。 7. parse count (total): 包括软解析和硬解析在内的总解析次数,用于计算软解析命中率。 8. parse ...

    sql执行详解

    - **减少硬解析和软解析**:硬解析是完全解析SQL,而软解析利用已解析的SQL(缓存在库缓存中)。通过配置`session_cached_cursors`,可以缓存游标以减少软解析,提高执行效率。 4. **优化访问路径**: - **索引...

    ORACLE SQL语句优化技术要点解析

    除此之外,还有其他优化策略,比如使用绑定变量代替硬解析,减少解析次数;使用覆盖索引避免全表扫描;通过分析和统计信息更新确保查询计划的准确性;合理设计索引,包括复合索引和函数索引;避免全表扫描,利用索引...

    Oracle动态性能视图[收集].pdf

    - **性能优化**:了解关键统计项如`CPU used by this session`(所有Session的CPU使用量)、`db block changes`(数据块变更次数)、`execute count`(执行的SQL语句数量)、`parse count (hard)`(硬解析次数)等...

    机械设计(第八版)课后习题集答案解析与解析(最新参考答案解析与解析).doc

    《机械设计》第八版课后习题集答案解析主要涵盖了材料疲劳极限、简化的等寿命寿命曲线绘制、机械零件的设计与安全系数计算等多个知识点。以下是这些知识点的详细解析: 1. **材料疲劳极限与循环次数的关系**: ...

    statspack示例

    硬解析次数高可能表明应用程序效率不高或数据库配置需要优化。 报告还提到了与SQL相关的统计信息,其中包括逻辑读取、物理读取、执行次数、调用和解析次数以及共享内存占用等。这些信息有助于分析SQL语句的性能问题...

    ORACLE资源详解

    2. **减少硬解析**:通过优化SQL语句、合理设置`cursor_sharing`参数以及调整`shared_pool_size`等措施减少硬解析次数。 3. **提高SQL重用率**:利用SQL绑定变量等技术提高SQL语句的重用率,减少不必要的解析操作。 ...

    怎么看AWR报告

    硬解析次数过多可能提示SQL重用率低的问题。 - **Hard parses**:硬解析次数。硬解析过多会增加系统的负担,可能需要优化SQL或调整共享池配置。 - **Sorts**:每秒/每事务的排序次数。频繁的排序操作可能与表结构...

    如何绑定变量

    绑定变量通过减少硬解析次数,降低了每次执行SQL语句时所需的资源开销,提高了整体性能。特别是在OLTP环境中,事务处理频繁且快速,绑定变量的应用对于保持系统的响应时间和吞吐量至关重要。 ### 如何使用绑定变量 ...

    Oracle AWR 报告分析实例讲解.docx

    - **Hard Parses**:硬解析次数过多可能意味着SQL语句的重用率不高,应考虑使用绑定变量或适当增加共享池大小以提高SQL重用率。 - **Redo Size**:较高的redo生成量可能意味着较高的事务活动或写入操作,需要注意...

    学习动态性能表_all_in_one

    6. `parse count (hard)`:在Shared Pool中未命中的解析调用次数,反映了硬解析的频率。 7. `parse count (total)`:总的解析调用次数,包括软解析和硬解析。 8. `parse time cpu`:总CPU解析时间(以10毫秒为单位)...

    Oracle_AWR_报告分析实例讲解

    5. **硬解析问题**:硬解析次数过高可能是由于SQL语句重用不足导致的,需要进一步检查SQL语句的编写方式以及相关的数据库参数配置。 #### 四、进一步行动 针对以上分析,建议采取以下措施: 1. **优化快照周期**...

Global site tag (gtag.js) - Google Analytics