WHERE clause predicates are sent as string literals. If you use precompilers to develop the application, then make sure to reset the parameters MAXOPENCURSORS,

HOLD_CURSOR, and RELEASE_CURSOR from the default values before precompiling the application

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

参数文件中的连个游标相关的值:

SQL> show parameter CURSORS

NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
open_cursors     integer300
session_cached_cursors     integer50

open_cursors:指明每个session最多能够打开的cursors的数量。

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

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

SELECT MAX(A.VALUE) AS HIGHEST_OPEN_CUR, P.VALUE AS MAX_OPEN_CUR  
      FROM V$SESSTAT A, V$STATNAME B, V$PARAMETER P  
     WHERE A.STATISTIC# = B.STATISTIC#  
       AND B.NAME = 'opened cursors current'  
       AND P.NAME = 'open_cursors'  
     GROUP BY P.VALUE;

HIGHEST_ OPEN CUR是实际打开的cursors 的最大值,MAX_OPEN_ CUR是参数Open_cursors的设定值,如果二者太接近,甚至触发eRA一01000错误,那么你就应该调大参数Open_cursors的设定值。

HOLD_CURSOR:是预编译程序中的一个参数,它指定了私有游标是否应该该被缓存,这里不做展开。

在分析工具tkprof中hard parse与soft parse被同等对待,都被认为是parse;软解析即会造成parse总数上升。

软解析避免了硬解析过程中的几个步骤,但仍包括了初始化的语法,语义解析并计算语句HASH值与SQL AREA中已有语句进行对比;若匹配则查询优化等昂贵的操作得以避免。

另请注意,10053事件仅在硬解析过程中被触发。

What are the Oracle Precompiler options HOLD_CURSOR and RELEASE_CURSOR and how do they affect the performance of a PCC program?

First of all, these options apply to implicit and explicit cursors in all precompiled languages except Pro*Ada. They apply ONLY to implicit cursors associated with INSERT, UPDATE, DELETE, or a single row SELECT in Pro*Ada. An explicit cursor in a program is one explicitly created with EXEC SQL DECLARE C1 CURSOR FOR...

This bulletin discusses what these options do internally and how changing them affects program performance.

HOLD_CURSOR is a precompiler command line parameter.

Summary Operation:
~~~~~~~~~~~~~~~~~~

NB: Both the soft and hard parse register as a parse in tkprof. If the cursor is open and it is not in the SQL_AREA then it clearly has to parse it (not shown in the diagram!)

The HOLD_CURSOR and RELEASE_CURSOR Options
------------------------------------------
.
Following will be a discussion of what these options do internally and how changing them affects program performance.

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 workarea 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:

How are the HOLD_CURSOR and RELEASE_CURSOR options related to this view?

The HOLD_CURSOR option deals with the link between the program cursor and its cache entry.

The RELEASE_CURSOR option deals with the link between the Oracle cursor and the cache entry.

For SQL statements that are FREQUENTLY RE-EXECUTED, the bottom line is this: if you want to maximize performance, make sure these SQL statements stay "glued" to their respective Oracle cursor.

What does it mean when a SQL statement is "glued" to its Oracle cursor?

It means that both links between the SQL statement and its Oracle cursor are made permanent.

Why would you want to keep a statement "glued" to its context area?
Because the context area contains the parsed statement and other information necessary to execute the statement, such as the addresses of the host variables. Maintaining access to this information makes subsequent execution of the statement much faster.

How do you "glue" a statement to a cache entry?

By correct use of the  HOLD_CURSOR and RELEASE_CURSOR options via the PCC command line or inline with EXEC ORACLE OPTION(...).

For instance, with HOLD_CURSOR=YES as the Oracle option, a cache entry cannot be flagged for reuse. This has important implications. If all cache entries have been used up and a new cache entry is needed for a new SQL statement such that the number of cache entries would now exceed the number specified in MAXOPENCURSORS, Oracle will use the first cache entry marked reuseable.

For example, in the above diagram, if the cache entry C(1) is marked reusable, and the program is about to execute the EXEC SQL SELECT...
(program cursor P(MAXOPENCURSORS+1), and the number of cache entries in use already equals MAXOPENCURSORS, cache entry C(1) and its Oracle
cursor will now be linked to the select statement. A subsequent execution of the insert statement would require pre-empting a cache entry and its Oracle cursor from another SQL statement and performing a reparse.

Correspondingly(相应的), with the default RELEASE_CURSOR=NO as the Oracle option, the link between the cache entry and the Oracle cursor (the con-
text area) is maintained after the statement is executed so that the  parsed statement and, more importantly, the allocated memory stay available.

The freeing up of this memory by RELEASE_CURSOR=YES means that the  next statement that gets linked to this cache entry will require an  expensive reallocation of memory in addition to a reparse. Ugh! Why  would anybody want RELEASE_CURSOR=YES? We will see later on.

Program cursor - - - - - [ Cursor cache entry ] - - - - - Oracle for SQL statement cursor
                         ^                                            ^
HOLD_CURSOR=YES                     RELEASE_CURSOR=NO
program cursor is permanently           cache entry maintains the
linked to its cache entry.                   address of its context area.

So the HOLD_CURSOR option is intimately tied to the MAXOPENCURSORS option. What exactly is the MAXOPENCURSORS option? First of all, MAX-
OPENCURSORS is a misnomer(用词不当). It should more appropriately be called INITIAL_CURSOR_CACHE_SIZE. (Okay, so it's a mouthful.) Anyway, if
all cursor cache entries are currently marked "not reusable" either because of the HOLD_CURSOR option or because the associated statement is currently being executed (an explicitly opened cursor is still being fetched on and hasn't been closed yet), then a request for a new cursor will actually result in the extension of the cursor cache at runtime (i.e. if MAXOPENCURSORS=10, and all 10 entries are active,then an 11th will be created).

Just letting the precompiler reuse the oldest cache entry won't always work, as the following example illustrates: Imagine the case where the user has ten explicitly declared  cursors opened, and wants to execute an eleventh. If the program actually reuses the oldest program cursor, the user would lose his current position in the first cursor and would not be able to fetch from it anymore.

By the way, if an eleventh cache entry is created, when that cursor is closed the eleventh entry is not removed. Setting MAXOPENCURSORS low saves memory, but causes potentially expensive dynamic allocations of  new cache entries if they're needed. Setting it high assures quick  execution, but may use more memory than necessary.

What if a statement is not executed repeatedly in a program?

Then you could go with the other options HOLD_CURSOR=NO and RELEASE_CURSOR=YES.   With the HOLD_CURSOR=NO option, the link between a program cursor and  its cache entry is not permanent. The cache entry is automatically  marked reusable in case it is needed. With the RELEASE_CURSOR=YES option, the Oracle cursor (the context area) is automatically freed and the parsed statement lost. A reason you might use this option is if  you are limited by the number of Oracle cursors (MAXOPENCURSORS) at your site due to memory issues. You may want to incur the cost of reallocating memory and reparsing in order to manage memory more effectively.

An advantage of setting RELEASE_CURSOR=YES is that until the link be-
tween the cache entry and the Oracle cursor (context area) is removed,
ORACLE keeps parse locks on any tables referenced in the SQL state-
ment. These parse locks prevent other users and you from ALTERing or
DROPping the tables (does ORA-0057 sound familiar?). Also, in Version
5, it will free up the read-consistent image of the referenced tables
stored in ORACLE's Before Image file.

What do we mean when we say that RELEASE_CURSOR=YES takes precedence
over HOLD_CURSOR=YES? With RELEASE_CURSOR=YES, the link between the
Oracle cursor and the cache entry is cut and the Oracle cursor is
freed (closed), so even if your program cursor is permanently linked
to the cache entry because HOLD_CURSOR=YES, you will still have to re-
allocate memory and reparse the statement. So subsequent executions
of a statement don't benefit from the HOLD_CURSOR=YES option because
RELEASE_CURSOR=YES.

For programmers experienced with OCI, here's the OCI equivalent of
what's happening: #define MAXOPENCURSORS 5 char     *sql_stmts[10];
curs_def cursor[MAXOPENCURSORS]; oopen(cursor[0],...);
osql3(cursor[0],...,sql_stmts[0],...);  An example of a "cache entry" being linked to another SQL statement
later on in the program is as follows: osql3(cursor[0],...,sql_stmts[5],...);  I am forced to reuse one of my "cache entries" to execute the sixth
SQL statement. An example of a context area being freed is:  oclose(cursor[0]);      Reusing cursor[0] would require another oopen() and another osql3()--
another dynamic allocation of memory and another reparse. Conclusion
---------- As a programmer, you will get the most from these options by using
them selectively inline rather than specifying them as options at pre-
compile time.Reference:Pro*C/C++ Precompiler Programmer's Guide

sql解析中参数MAXOPENCURSORS, HOLD_CURSOR, and RELEASE_CURSOR 的解释相关推荐

  1. SqlParameter[] 数组 sql语句中参数的填充的通用访问类的使用方法

    //1.定义通用访问类的方法 public static SqlDataReader GetReader(string sql,SqlParameter [] para) { //实例化conn Sq ...

  2. SQL解析在美团点评中的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  3. SQL解析在美团的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  4. sql 解析字符串添加到临时表中 sql存储过程in 参数输入

    sql 解析字符串添加到临时表中  sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表   FROM dbo.Func_SplitOneCol ...

  5. Oracle中SQL解析的流程

    Oracle中SQL解析的主要流程: 我们说的游标概念比较复杂,它可以是客户端程序中的游标,服务进程中的私有游标,以及服务器端共享池里的共享游标.假设一个游标被打开了,一般来说它的共享游标信息(包括执 ...

  6. 读书笔记:SQL 查询中的SQL*Plus 替换变量(DEFINE变量)和参数

    本文为"SQL*Plus 替换变量 - 在 SQL 查询中定义变量和参数"的读书笔记. 此文主要是讲替换变量,也称为DEFINE变量,但也涉及了绑定变量和SQL Plus系统变量. ...

  7. Oracle怎么获取json类型字符串值,sql解析json格式字段 如何获取json中某个字段的值?...

    java将json数据解析为sql语句?小编给你倒一杯热水.可你惦记着其他饮料,所以你将它放置一旁.等你想起那杯水时,可惜它已经变得冰冷刺骨. 图片中是json数据,每个数据的开头都有表名称,操作类型 ...

  8. Entity Framework 在MySQL中执行SQL语句,关于参数问题

    在Entity Framework中添加MySQL模型,在写代码的过程中需要直接执行SQL语句. 在SQL语句中用到了@curRank := 0 这样在SQL语句中定义参数,同时还会有传入参数:ai. ...

  9. java---编写一个方法,返回一个int型的二维数组,数组中的元素通过解析字符串参数获得。

    题目: 编写一个方法,返回一个int型的二维数组,数组中的元素通过解析字符串参数获得,字符串如下"1,2:3,4,5:6,7"对应的数组为: d[0][0]=1 d[0][1]=2 ...

最新文章

  1. laravel json字段添加_Laravel 6.0.4 中将添加计划任务事件
  2. Bag of Features (BOF)图像检索算法
  3. getRunningTasks和getRunningAppProcesses失效
  4. 电路板必须用c语言编程吗,上大学才知道绿油油的板子叫PCB,如何成为一名电子工程师...
  5. 工程制图 (机件常用的基本表示法)
  6. arguments使用
  7. 学java专科_专科学历可以学习java开发吗
  8. 【LeetCode】Remove Nth Node From End of List
  9. VB模拟指针模块mPoint.bas
  10. MongoDB,还有一个角度看数据
  11. CentOS下编译安装Gcc-4.9
  12. php登录界面模板美化,一款简单好看的登录界面——Typecho美化包 Sign-Page-For-Typecho...
  13. xshell5 可用注册码
  14. 适合儿童学习的编程语言一览
  15. JAVA 解密M3U8 视频TS片断提示:Wrong IV length: must be 16 bytes long 解决方法
  16. linux gzip 加密,gzip命令
  17. java emoji表情_java emoji表情存储的解决方法
  18. 如何理解移动数据和移动计算
  19. C语言中的%p是什么意思?
  20. JS打开选择本地文件的对话框

热门文章

  1. MPB:中科院城环所杨军组-​​基于DNA宏条形码的水体微型真核生物群落测序建库方法...
  2. 三大移动平台概览:移动游戏开发者生存必读
  3. 高项.2021案例默写
  4. java项目-第137期jsp+servlet的周公算命预测系统-java毕业设计
  5. 2022年9月青少年软件编程(图形化)等级考试试卷--三级--数星星
  6. Docker将会在Windows和MAC平台本地化
  7. 第一次用计算机证明的数学定理是,勾股定理是一个基本几何定理,是人类早期发现并证明的重要数学定理之一,用代数思想解决几何...
  8. 基于CCD摄像头智能车分段PID控制算法设计
  9. matlab隐形眼镜类型预测,决策树预测隐形眼镜类型
  10. 本地图片转为网络链接(URL/HTML/Markdown/BBCode...)