Oracle 变量绑定与变量窥视合集系列二

用示例演示一次硬分析(hard parse)和一次软分析(soft parse),以及一次更软的分析(softer soft parse),并对给出演示结果

我们先看一个硬解析和软解析关系测试,什么时候硬解析,什么时候软解析

LEO1@LEO1> drop table leo6 purge;                          清理环境

Table dropped.

LEO1@LEO1> create table leo6 as select * from dba_objects;      创建leo6表

Table created.

LEO1@LEO1> select count(*) from leo6;                       第一次执行

  COUNT(*)

----------

     72011

LEO1@LEO1> select sql_text,parse_calls,loads,executions from v$sql where sql_text like 'select count(*) from leo6' order by 1;

SQL_TEXT                             PARSE_CALLS  LOADS   EXECUTIONS

-------------------------------------------------- ----------- -------------------------- ----------- ---------- ------------------

select count(*) from leo6                 1           1        1

总解析次数:1

硬解析次数:1

执行次数:1

硬解析发生在SQL语句第一次执行时,后续在执行相同语句就是软解析了,看看下面

LEO1@LEO1> select count(*) from leo6;                       第二次执行

  COUNT(*)

----------

     72011

LEO1@LEO1> select sql_text,parse_calls,loads,executions from v$sql where sql_text like 'select count(*) from leo6' order by 1;

SQL_TEXT                             PARSE_CALLS  LOADS   EXECUTIONS

-------------------------------------------------- ----------- -------------------------- ----------- ---------- ------------------

select count(*) from leo6                 2           1        2

总解析次数:2

硬解析次数:1

执行次数:2

当SQL硬解析之后,后续相同的SQL都被软解析,除非SQL被剔除shared_pool

LEO1@LEO1> alter system flush shared_pool;       清空shared_pool

System altered.

LEO1@LEO1> select count(*) from leo6;            重新执行一次

  COUNT(*)

----------

     72011

LEO1@LEO1> select sql_text,parse_calls,loads,executions from v$sql where sql_text like 'select count(*) from leo6' order by 1;

SQL_TEXT                             PARSE_CALLS  LOADS   EXECUTIONS

-------------------------------------------------- ----------- -------------------------- ----------- ---------- ------------------

select count(*) from leo6                 1           1        1

当重新执行一次后,又重新有了一次硬解析,oracle认为这是一条新SQL,根据统计信息重新生成一次执行计划来执行。

Softer_soft_parse 会话对游标的缓存

什么是游标:游标可以理解为SQL语句的一个句柄,也叫SQL语句的指针,游标指向一条SQL语句,oracle会话要执行一条SQL时,首先要打开游标。

打开游标:新的SQL语句执行时候,在SGA中需要把这条SQL语句和shared_pool中SQL语句的哈希值建立一条通道(连接),即建立SQL语句句柄,这个建立通道的过程就叫打开游标。

softer_soft_parse超软解析:打开游标的过程是在软解析之后,它要在shared_pool中寻找哈希值(这个哈希值就是软解析之后得到的),如果没有找到就需要重新构造游标(这就是硬解析过程),如果游标是打开状态,那么会话可以直接使用打开的游标连接到shared_pool中SQL语句入口,执行SQL。如果游标是关闭状态,会话就需要重新建立到shared_pool连接(即打开游标操作),这样也会消耗一点点资源。而我们要做的就是尽量打开游标保持通道畅通,又由于这个操作是在软解析之后,又叫超软解析,比软解析还要软一点。

会话缓存游标实验

session_cached_cursor,这个参数可以控制,会话打开游标或关闭游标

如果值为0,说明不使用缓存游标功能,oracle每次都要重新打开游标

如果值为非0,说明使用缓存游标功能,会话一直保持打开状态,随时执行SQL语句

1.session_cached_cursors=0 测试

为了更好的对比效果,我们先要清空一下内存中的遗留数据,最简行以便的方法就是重启数据库了,当然我们这是测试环境,在生产环境中另当别论。

SYS@LEO1> shutdown immediate;               关闭数据库,清空SGA

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@LEO1> startup                           启动数据库

ORACLE instance started.

Total System Global Area  680607744 bytes

Fixed Size                  2216464 bytes

Variable Size             503320048 bytes

Database Buffers          167772160 bytes

Redo Buffers                7299072 bytes

Database mounted.

Database opened.

SYS@LEO1> conn leo1/leo1                    切换leo1用户

Connected.

LEO1@LEO1> set linesize 300                   设置版面

LEO1@LEO1> set pagesize 999

LEO1@LEO1> show parameter session_cached_cursors

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------------------

session_cached_cursors                   integer      50

检查参数默认为50

LEO1@LEO1> alter session set session_cached_cursors=0;

Session altered.

如果值为0,说明不使用缓存游标功能,oracle每次都要重新打开游标

LEO1@LEO1> show parameter session_cached_cursors

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------------------

session_cached_cursors                   integer      0

LEO1@LEO1> alter system flush shared_pool;       清空shared pool

System altered.

LEO1@LEO1> select 'STAT-'||name,value from v$sysstat where name like '%parse%' or name like'%cursor%'

union all

select 'LATCH-'||name,gets from v$latch where name = 'shared pool';

'STAT-'||NAME                                VALUE

---------------------------------------------------------------------- ----------

STAT-opened cursors cumulative                  51660

STAT-opened cursors current                     88          当前打开游标数

STAT-pinned cursors current                      5

STAT-session cursor cache hits                    37902       会话缓冲区游标命中率

STAT-session cursor cache count                  3153

STAT-cursor authentications                      668

STAT-parse time cpu                            845         CPU解析耗时

STAT-parse time elapsed                         1974        解析总耗时

STAT-parse count (total)                         30593       解析总次数

STAT-parse count (hard)                         2700        硬解析次数

STAT-parse count (failures)                       6

STAT-parse count (describe)                      0

LATCH-shared pool                             263201       共享池latch数

查询系统当前资源消耗情况

LEO1@LEO1> drop table leo7 purge;                           清空环境

Table dropped.

LEO1@LEO1> create table leo7 as select * from dba_objects;       创建leo7表

Table created.

LEO1@LEO1> select count(*) from leo7;                        表size71972条

  COUNT(*)

----------

     71972

循环执行1w次

LEO1@LEO1> begin

for leo in 1..10000 loop

execute immediate 'select count(*) from leo7';

end loop;

end;

/

PL/SQL procedure successfully completed.

再次查询一下当前系统资源消耗情况

LEO1@LEO1> select 'STAT-'||name,value from v$sysstat where name like '%parse%' or name like'%cursor%'

union all

select 'LATCH-'||name,gets from v$latch where name = 'shared pool';  2    3  

'STAT-'||NAME                                 VALUE

---------------------------------------------------------------------- ----------

STAT-opened cursors cumulative                   63614

STAT-opened cursors current                      89      当前打开游标数

STAT-pinned cursors current                       6

STAT-session cursor cache hits                     39494   会话缓冲区游标命中率

STAT-session cursor cache count                   3513

STAT-cursor authentications                       713

STAT-parse time cpu                             851

STAT-parse time elapsed                          1992

STAT-parse count (total)                          41546   解析总次数

STAT-parse count (hard)                          2739    硬解析次数

STAT-parse count (failures)                        6

STAT-parse count (describe)                       0

LATCH-shared pool                              268172

这是session_cached_cursors=0的对比结果

当前打开游标数:88  ->  89   多了1个

会话缓冲区游标命中率:37902   ->   39494   多了1592次

硬解析次数:2700  ->  2739   多了39次

解析总次数:30593  ->  41546  多了10953次,这个和执行的次数很接近,差不多软解析了1w次

共享池latch数:263201  ->  268172   多了4971次

2.session_cached_cursors=100 测试

系统当前资源消耗

LEO1@LEO1> select 'STAT-'||name,value from v$sysstat where name like '%parse%' or name like'%cursor%'

union all

select 'LATCH-'||name,gets from v$latch where name = 'shared pool';  2    3  

'STAT-'||NAME                                 VALUE

---------------------------------------------------------------------- ----------

STAT-opened cursors cumulative                   80112

STAT-opened cursors current                      88

STAT-pinned cursors current                      5

STAT-session cursor cache hits                    44463

STAT-session cursor cache count                  4334

STAT-cursor authentications                      791

STAT-parse time cpu                            872

STAT-parse time elapsed                         2016

STAT-parse count (total)                         55199

STAT-parse count (hard)                         2771

STAT-parse count (failures)                       10

STAT-parse count (describe)                      0

LATCH-shared pool                             278343

LEO1@LEO1> alter session set session_cached_cursors=100;      

如果值为非0,说明使用缓存游标功能,会话一直保持打开状态,随时执行SQL语句

LEO1@LEO1> show parameter session_cached_cursors

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

session_cached_cursors               integer     100

再重新循环执行1w次

LEO1@LEO1> begin

for leo in 1..10000 loop

execute immediate 'select count(*) from leo7';

end loop;

end;

/

PL/SQL procedure successfully completed.

LEO1@LEO1> select 'STAT-'||name,value from v$sysstat where name like '%parse%' or name like'%cursor%'

union all

select 'LATCH-'||name,gets from v$latch where name = 'shared pool';  

'STAT-'||NAME                                 VALUE

---------------------------------------------------------------------- ----------

STAT-opened cursors cumulative                   92040

STAT-opened cursors current                      89

STAT-pinned cursors current                       5

STAT-session cursor cache hits                     56058

STAT-session cursor cache count                   4690

STAT-cursor authentications                       803

STAT-parse time cpu                             872

STAT-parse time elapsed                          2017

STAT-parse count (total)                          56081

STAT-parse count (hard)                          2773

STAT-parse count (failures)                        10

STAT-parse count (describe)                       0

LATCH-shared pool                              280878

这是session_cached_cursors=100的对比结果

当前打开游标数:88  ->  89   多了1个

会话缓冲区游标命中率:44463   ->   56058   多了11595多

硬解析次数:2771  ->  2773   多了2次

解析总次数:55199  ->  56081  多了882次

共享池latch数:278343  ->  280878   多了2535次

小结:我们从会话缓冲区游标命中率指标的对比结果可知,设置session_cached_cursors参数为非0时,oracle使用了缓存游标功能,命中率从1592提升到11595,共享池latch数从4971减少到2535,我们可以很明显的看出使用打开游标技术可以大大提高数据库的性能,softer_soft_parse超软解析可以提供比soft_parse软解析更好的性能。

 

你可能感兴趣的:(bind,绑定变量,软解析,硬解析,peeking)