当客户端进程,将SQL语句通过监听器发送到Oracle
时, 会触发一个Server process
生成,来对该客户进程服务。Server process
得到SQL语句之后,对SQL语句进行Hash
运算,然后根据Hash
值到library cache
中查找,如果存在,则直接将library cache
中的缓存的执行计划拿来执行,最后将执行结果返回该客户端,这种SQL解析叫做软解析;如果不存在,则会对该SQL进行解析parse
,然后执行,返回结果,这种SQL解析叫做硬解析。
1.硬解析的步骤
硬解析一般包括下面几个过程:
1)对SQL语句进行语法检查,看是否有语法错误。比如select from where
等的拼写错误,如果存在语法错误,则推出解析过程;
2)通过数据字典(row cache
),检查SQL语句中涉及的对象和列是否存在。如果不存在,则推出解析过程。
3)检查SQL语句的用户是否对涉及到的对象是否有权限。如果没有则推出解析;
4)通过优化器创建一个最优的执行计划。这个过程会根据数据字典中的对象的统计信息,来计算多个执行计划的cost
,从而得到一个最优的执行计划。这一步涉及到大量的数据运算,从而会消耗大量的CPU资源;(library cache
最主要的目的就是通过软解析来减少这个步骤);
5)将该游标所产生的执行计划,SQL
文本等装载进library cache
中的heap
中。
2.软解析
所谓软解析,就是因为相同文本的SQL语句存在于library cache
中,所以本次SQL语句的解析就可以去掉硬解析中的一个活多个步骤。从而节省大量的资源的耗费。
3.软软解析
所谓的软软解析,就是不解析。当设置了session_cached_cursors
参数时,当某个session
第三次执行相同的SQL语句时,则会把该SQL语句的游标信息转移到该session
的PGA中。这样,当该session
在执行该SQL语句时,会直接从PGA
中取出执行计划,从而跳过硬解析的所有步骤。
SQL> show parameter cursor;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing string EXACT
cursor_space_for_time boolean FALSE
open_cursors integer 300
session_cached_cursors integer 20
open_cursors
设定每个session
(会话)最多能够同时打开多少个cursors
(游标)。
SESSION_CACHED_CURSORS
的值就是说的是一个session
可以缓存多少个cursor
,让后续相同的SQL语句不再打开游标,从而避免软解析的过程来提高性能。(绑定变量是解决硬解析的问题),软解析同硬解析一样,比较消耗资源.所以这个参数非常重要。
oracle
有一个概念,那就是session cursor cache
,中文描述就是有一块内存区域,用来存储关闭了的cursor
。当一个cursor
关闭之后,oracle
会检查这个cursor
的request
次数是否超过3次,如果超过了三次,就会放入session cursor cache
,这样在下次parse
的时候,就可以从session cursor cache
中找到这个statement, session cursor cache
的管理也是使用LRU
。
session_cached_cursors
这个参数是控制session cursor cache
的大小的。session_cached_cursors
定义了session cursor cache
中存储的cursor
的个数。这个值越大,则会消耗的内存越多。
另外检查这个参数是否设置的合理,可以从两个statistic
来检查。
SQL> select name,value from v$sysstat where name like '%cursor%';
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors cumulative 16439
opened cursors current 55
session cursor cache hits 8944
session cursor cache count 101
cursor authentications 353
SQL> select name,value from v$sysstat where name like '%parse%';
NAME VALUE
---------------------------------------------------------------- ----------
parse time cpu 0
parse time elapsed 0
parse count (total) 17211
parse count (hard) 1128
parse count (failures) 2
parse count(total)
就是总的parse
次数中,session cursor cache hits
就是在session cursor cache
中找到的次数,所占比例越高,性能越好。如果比例比较低,并且有剩余内存的话,可以考虑加大该参数。
Oracle 9i及以前,该参数缺省是0,10G上缺省是20。