什么是oracle中的游标


SQL Parsing Flow Diagram [ID 32895.1]

1. A cursor is an address on the client that points to the memory location of a SQL statement on the server. Multiple-client cursors may point at the same address

on the server.

2. Remember that 'Client' and 'Server' sides may reside on the same machine - in which case Client/Server is a logical distinction.

3. If a cursor is open, then the statement will be in the sql_area, so no parsing is necessary. This is why locks may remain when a client is terminated abnormally

(such as a PC Client being turned off without closing open cursors).

4. SESSION_CACHED_CURSORS is the initialisation parameter that specifies how many cursors to hold open for a particular session.

The open cursor request will still be sent to the server but it will not be executed once a matching cursor is found in the session cursor cache.

我们说的游标概念比较复杂,它可以是客户端程序中的游标,服务进程中的私有游标,以及服务器端共享池里的共享游标。假设一个游标被打开了,一般来说它的共享游标信息(包括执行计划,优化树等)总是会在SQL AREA里,无需再次软/硬解析。

SESSION_CACHED_CURSORS是Oracle中的一个初始化参数(修改必须重启实例),指定了每个会话缓存的游标上限(保留在PGA中);客户端程序中open cursor的要求仍会被传递给服务进程,服务进程首先扫描自身缓存的游标信息,如果命中则可以避免软解析,也有人称它为“软软解析”。

bb


下面是内容摘自Precompiler HOLD_CURSOR and RELEASE_CURSOR Options [ID 2055810.6]


What exactly do we mean by CURSOR? Unfortunately, we mean two different

things:

1. The program cursor - A data structure associated with a SQL

statement.

A program cursor is declared for each SQL statement that the

precompiler finds in your program. For the statements

EXEC SQL DECLARE SEL_EMP_CURS CURSOR FOR...

EXEC SQL INSERT...

PCC will declare two program cursors, say c1 and c2.

2. The Oracle cursor (also called the context area) - The work

area created dynamically at run time; this area contains the

parsed statement, the addresses of the host variables, and

other information necessary to execute the SQL statement.

These two cursors are linked together via the cursor cache. The initial

size of the cursor cache is determined by the MAXOPENCURSORS option.

The following diagram illustrates the relationship described above after

an insert and an update have been executed in your program:


EXEC SQL INSERT... | Cache entry | Oracle

Program cursor P(1)

+-----------------+

EXEC SQL UPDATE... | Cache entry | Oracle

Program cursor P(2)

+-----------------+

. . .

. . .

+-----------------+

EXEC SQL DELETE... | Cache entry |

Pgm cursor P(MAXOPENCURSORS) |P(MAXOPENCURSORS)|

+-----------------+

EXEC SQL SELECT...

Pgm cursor P(MAXOPENCURSORS+1)

etc...


open_cursors和SESSION_CACHED_CURSORS

open_cursors
OPEN_CURSORS specifies the maximum number of open cursors (handles to private SQL areas) a session can have at once. You can use this parameter to prevent a session from opening an excessive number of cursors.

这个缓存的区域应该是在pga中
SESSION_CACHED_CURSORS specifies the number of session cursors to cache. Repeated parse calls of the same SQL (including recursive SQL) or PL/SQL statement cause the session cursor for that statement to be moved into the session cursor cache. Subsequent parse calls will find the cursor in the cache and do not need to reopen the cursor. Oracle uses a least recently used algorithm to remove entries in the session cursor cache to make room for new entries when needed.



通过下面的资料,sql语句在进入的时候应该是会在pga中也有一个寻找的过程,这个过程是最快速的了,而且只会在自己会话中寻找。这个要理解好了,下面那个图很重要。

  1. SQL> show parameter open_cursors           --每个session(会话)最多能同时打开多少个cursor(游标)  
  2.   
  3. NAME                                 TYPE        VALUE  
  4. ------------------------------------ ----------- ------------------------------  
  5. open_cursors                         integer     300  
  6. SQL> show parameter session_cached_cursor  --每个session(会话)最多可以缓存多少个关闭掉的cursor  
  7.   
  8. NAME                                 TYPE        VALUE  
  9. ------------------------------------ ----------- ------------------------------  
  10. session_cached_cursors               integer     20  
  11. SQL> select count(*) from v$open_cursor;  --是指当前实例的某个时刻的打开的cursor数目

      COUNT(*)

      
  12. ----------  
  13.        108  

1、open_cursors与session_cached_cursor的作用?

open_cursors设定每个session(会话)最多能同时打开多少个cursor(游标)。session_cached_cursor设定每个session(会话)最多可以缓存多少个关闭掉的cursor。想要弄清楚他们的作用,我们得先弄清楚oracle如何执行每个sql语句。

看完上图后我们明白了两件事:

a、两个参数之间没有任何关系,相互也不会有任何影响。b、两个参数有着相同的作用:让后续相同的sql语句不在打开游标,从而避免软解析过程来提供应用程序的效率。

 

2、如何正确合理设置参数的大小?
a、如果Open_cursors设置太小,对系统性能不会有明显改善,还可能触发ORA-O1000:m~imum open CUrsOrs exceeded.的错误。如果设置太大,则无端消耗系统内存。我们可以通过如下的sql语句查看你的设置是否合理:

  1. SQL> SELECT MAX(A.VALUE) AS HIGHEST_OPEN_CUR, P.VALUE AS MAX_OPEN_CUR  
  2.   2    FROM V$SESSTAT A, V$STATNAME B, V$PARAMETER P  
  3.   3   WHERE A.STATISTIC# = B.STATISTIC#  
  4.   4     AND B.NAME = 'opened cursors current'  
  5.   5     AND P.NAME = 'open_cursors'  
  6.   6   GROUP BY P.VALUE;  
  7.   
  8. HIGHEST_OPEN_CUR MAX_OPEN_CUR  
  9. ---------------- --------------------  
  10.               28 300  

HIGHEST_ OPEN CUR是实际打开的cursors 的最大值,MAX_OPEN_ CUR是参数Open_cursors的设定值,如果二者太接近,甚至触发eRA一01000错误,那么你就应该调大参数Open_cursors的设定值。如果问题依旧没有解决,盲目增大Open_cursors也是不对的,这个时候你得检查应用程序的代码是否合理,比如说应用程序是否打开了游标,却没有在它完成工作后没有及时关闭。以下语句可以帮助你确定导致游标漏出的会话:

  1. SELECT A.VALUE, S.USERNAME, S.SID, S.SERIAL#  
  2.   FROM V$SESSTAT A, V$STATNAME B, V$SESSION S  
  3.  WHERE A.STATISTIC# = B.STATISTIC#  
  4.    AND S.SID = A.SID  
  5.    AND B.NAME = 'opened cursors curent';  

b、同样,session_cached_cursors的值也不是越大越好,我们可以通过下面两条语句得出合理的设置。

  1. SQL> SELECT NAME, VALUE FROM V$SYSSTAT WHERE NAME LIKE '%cursor%';  
  2.   
  3. NAME                                                                  VALUE  
  4. ---------------------------------------------------------------- ----------  
  5. opened cursors cumulative                                             15095  
  6. opened cursors current                                                   34  
  7. session cursor cache hits                                             12308  
  8. session cursor cache count                                              775  
  9. cursor authentications                                                  324  
  10.   
  11. SQL> SELECT NAME, VALUE FROM V$SYSSTAT WHERE NAME LIKE '%parse%';  
  12.   
  13. NAME                                                                  VALUE  
  14. ---------------------------------------------------------------- ----------  
  15. parse time cpu                                                          332  
  16. parse time elapsed                                                     1190  
  17. parse count (total)                                                    9184  
  18. parse count (hard)                                                     1031  
  19. parse count (failures)                                                    3  

session cursor cache hits就是系统在高速缓存区中找到相应cursors的次数,parse count(total)就是总的解析次数,二者比值越高,性能越好。如果比例比较低,并且有较多剩余内存的话,可以考虑加大该参数。

 

c、使用下面的sql判断'session_cached_cursors' 的使用情况。如果使用率为100%则增大这个参数值。

  1. SQL> SELECT 'session_cached_cursors' PARAMETER,  
  2.   2         LPAD(VALUE, 5) VALUE,  
  3.   3         DECODE(VALUE, 0, ' n/a', TO_CHAR(100 * USED / VALUE, '990') || '%') USAGE  
  4.   4    FROM (SELECT MAX(S.VALUE) USED  
  5.   5            FROM V$STATNAME N, V$SESSTAT S  
  6.   6           WHERE N.NAME = 'session cursor cache count'  
  7.   7             AND S.STATISTIC# = N.STATISTIC#),  
  8.   8         (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'session_cached_cursors')  
  9.   9  UNION ALL  
  10.  10  SELECT 'open_cursors',  
  11.  11         LPAD(VALUE, 5),  
  12.  12         TO_CHAR(100 * USED / VALUE, '990') || '%'  
  13.  13    FROM (SELECT MAX(SUM(S.VALUE)) USED  
  14.  14            FROM V$STATNAME N, V$SESSTAT S  
  15.  15           WHERE N.NAME IN  
  16.  16                 ('opened cursors current''session cursor cache count')  
  17.  17             AND S.STATISTIC# = N.STATISTIC#  
  18.  18           GROUP BY S.SID),  
  19.  19         (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'open_cursors');  
  20.   
  21. PARAMETER              VALUE      USAGE  
  22. ---------------------- ---------- -----  
  23. session_cached_cursors    20       100%  
  24. open_cursors             300        16%  

当我们执行一条sql语句的时候,我们将会在shared pool产生一个library cache object,cursor就是其中针对于sql语句的一种library cache object.另外我们会在pga有一个cursor的拷贝,同时在客户端会有一个statement handle,这些都被称为cursor,在v$open_cursor里面我们可以看到当前打开的cursor和pga内cached cursor.

-------上面这段话很重要,理解好各种cursor,客户端的那个应该就是我们平常说到的取数的游标,和我们这里说的内存中的cursor是两个概念,一定要分清楚。


session_cached_cursor
这个参数限制了在pga内session cursor cache list的长度,session cursor cache list是一条双向的lru链表,当一个session打算关闭一个cursor时,如果这个cursor的parse count超过3次,那么这个cursor将会被加到session cursor cache list的MRU端.当一个session打算parse一个sql时,它会先去pga内搜索session cursor cache list,如果找到那么会把这个cursor脱离list,然后当关闭的时候再把这个cursor加到MRU端.session_cached_cursor提供了快速软分析的功能,提供了比soft parse更高的性能.

fj.png57996404a9e46b0b47a9e3405d9af654.gif

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28952551/viewspace-765045/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28952551/viewspace-765045/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值