http://www.itpub.net/thread-877110-1-5.html
Subject: SQL Parsing Flow Diagram
Doc ID: Note:32895.1 Type: REFERENCE
Last Revision Date: 20-OCT-2005 Status: PUBLISHED
PURPOSE
~~~~~~~
The document gives a overview of Parsing.
SCOPE & APPLICATION
~~~~~~~~~~~~~~~~~~~
For users requiring a general overview of how parsing works.
Introduction
============
This article show the parsing mechanism as a flow diagram.
Its main purpose is to show the difference between a 'soft' and a
'hard' parse.
It is intended to give a feel of how parsing operates to make
explanation of parsing activity easier.
SQL Parsing Flow Diagram
========================
NOTESPHP code:
Statement
Submitted
|
Is it in an open cursor?--------------YES----V
| |
NO |
| |
Is SESSION_CACHED_CURSORS = Value |
and cursor in --------------YES----V In these 3 cases we
Session Cursor cache? | know that the cursor has
| | already been parsed, so
NO | re-parsing is
| | unnecessary.
Is HOLD_CURSOR=Y |
and cursor in --------------YES----V
Held cursor cache? |
| |
NO |
| | ^
OPEN A CURSOR | CLIENT SIDE |
| | -------------|
Statement is Hashed and compared | SERVER SIDE |
with the Hashed value in the sql area | V
| V
Is it in sql area? --YES-(Soft Parse)--> ---------
| | |
NO | EXECUTE |
| | |
PARSE STATEMENT ('Hard' Parse)---------> ---------
----------------------
from Oracle doc(Oracle Database Programmer's Guide to the Oracle Precompilers
10gR2))
Eliminating unnecessary parsing requires correct handling of cursors and selective use of the following cursor management options:
These options affect implicit and explicit cursors, the cursor cache, and private SQL areas.
You can use the ORACA to get cursor cache statistics. See "Using the Oracle Communications Area".
Recall that there are two types of cursors: implicit and explicit.
Oracle implicitly declares a cursor for all data definition and data
manipulation statements. However, for queries that return more than one
row, you must explicitly declare a cursor (or use host arrays). You use
the DECLARE CURSOR statement to declare an explicit cursor. How you handle the opening and closing of explicit cursors affects performance.
If you need to reevaluate the active set, simply reopen the cursor. The OPEN statement will use any new host-variable values. You can save processing time if you do not close the cursor first.
To make performance tuning
easier, the precompiler lets you reopen an already open cursor. However,
this is an Oracle extension to the ANSI/ISO embedded SQL standard. So,
when MODE=ANSI, you must close a cursor before reopening it.
Only CLOSE a cursor when you want to free the resources
(memory and locks) acquired by opening the cursor. For example, your
program should close all cursors before exiting.
In general, there are three ways to control an explicitly declared cursor:
Use the DECLARE, OPEN, and CLOSE statements
Use the PREPARE, DECLARE, OPEN, and CLOSE statements
COMMIT closes the cursor when MODE=ANSI
With the first way, beware of unnecessary parsing. The OPEN
statement does the parsing, but only if the parsed statement is
unavailable because the cursor was closed or never opened. Your program
should DECLARE the cursor, reopen it every time the value of a host variable changes, and CLOSE it only when the SQL statement is no longer needed.
With the second way (dynamic SQL Methods 3 and 4), the PREPARE statement does the parsing, and the parsed statement is available until a CLOSE statement is executed. Your program should prepare the SQL statement and DECLARE
the cursor, reopen the cursor every time the value of a host variable
changes, rePREPARE the SQL statement and reopen the cursor if the SQL
statement changes, and CLOSE the cursor only when the SQL statement is no longer needed.
When possible, avoid placing OPEN and CLOSE statements in a loop; this is a potential cause of unnecessary reparsing of the SQL statement. In the next example, both the OPEN and CLOSE statements are inside the outer while loop. When MODE=ANSI, the CLOSE statement must be positioned as shown, because ANSI requires a cursor to be closed before being reopened.
EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ename, sal from emp where sal > :salary and
sal <= :salary + 1000;
salary = 0;
while (salary < 5000)
{
EXEC SQL OPEN emp_cursor;
while (SQLCODE==0)
{
EXEC SQL FETCH emp_cursor INTO ....
...
}
salary += 1000;
EXEC SQL CLOSE emp_cursor;
}
With MODE=ORACLE, however, a CLOSE statement can execute without the cursor being opened. By placing the CLOSE statement outside the outer while loop, you can avoid possible reparsing at each iteration of the OPEN statement.
...
while (salary < 5000)
{
EXEC SQL OPEN emp_cursor;
while (sqlca.sqlcode==0)
{
EXEC SQL FETCH emp_cursor INTO ....
...
}
salary += 1000;
}
EXEC SQL CLOSE emp_cursor;
A SQL statement need be parsed only once unless you change its
makeup. For example, you change the makeup of a query by adding a column
to its select list or WHERE clause. The HOLD_CURSOR, RELEASE_CURSOR, and MAXOPENCURSORS
options give you some control over how Oracle manages the parsing and
reparsing of SQL statements. Declaring an explicit cursor gives you
maximum control over parsing.
When a data manipulation statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache is a continuously updated area of memory used for cursor management. The cursor cache entry is in turn linked to a private SQL area.
The private SQL area, a work area created dynamically at run time by Oracle, contains the parsed SQL statement, the addresses of host variables, and other information needed to process the statement. An explicit cursor lets you name a SQL statement, access the information in its private SQL area, and, to some extent, control its processing.
represents the cursor cache after your program has done an insert and a delete.
Figure C-2 Cursors Linked through the Cursor Cache

The maximum number of open cursors in each user session is set by the Oracle initialization parameter OPEN_CURSORS.
MAXOPENCURSORS specifies the initial
size of the cursor cache. If a new cursor is needed and there are no
free cache entries, Oracle tries to reuse an entry. Its success depends
on the values of HOLD_CURSOR and RELEASE_CURSOR and, for explicit cursors, on the status of the cursor itself.
If the value of MAXOPENCURSORS is less than the number
of cache entries actually needed, Oracle uses the first cache entry
marked as reusable. For example, suppose the cache entry E(1) for an INSERT statement is marked as reusable, and the number of cache entries already equals MAXOPENCURSORS. If the program executes a new statement, cache entry E(1) and its private SQL area might be reassigned to the new statement. To reexecute the INSERT statement, Oracle would have to reparse it and reassign another cache entry.
Oracle allocates an additional cache entry if it cannot find one to reuse. For example, if MAXOPENCURSORS=8
and all eight entries are active, a ninth is created. If necessary,
Oracle keeps allocating additional cache entries until it runs out of
memory or reaches the limit set by OPEN_CURSORS. This dynamic allocation adds to processing overhead.
Thus, specifying a low value for MAXOPENCURSORS saves
memory but causes potentially expensive dynamic allocations and
deallocations of new cache entries. Specifying a high value for MAXOPENCURSORS assures speedy execution but uses more memory.
Sometimes, the link between an infrequently executed SQL statement and its private SQL area should be temporary.
When HOLD_CURSOR=NO (the default), after Oracle executes
the SQL statement and the cursor is closed, the precompiler marks the
link between the cursor and cursor cache as reusable. The link is reused
as soon as the cursor cache entry to which it points is needed for
another SQL statement. This frees memory allocated to the private SQL
area and releases parse locks. However, because a prepared cursor must
remain active, its link is maintained even when HOLD_CURSOR=NO.
When RELEASE_CURSOR=YES,
after Oracle executes the SQL statement and the cursor is closed, the
private SQL area is automatically freed and the parsed statement lost.
This might be necessary if, for example, MAXOPENCURSORS is set low at your site to conserve memory.
If a data manipulation statement precedes a data definition statement and they reference the same tables, specify RELEASE_CURSOR=YES
for the data manipulation statement. This avoids a conflict between the
parse lock obtained by the data manipulation statement and the
exclusive lock required by the data definition statement.
When RELEASE_CURSOR=YES, the link between the private
SQL area and the cache entry is immediately removed and the private SQL
area freed. Even if you specify HOLD_CURSOR=YES, Oracle must still reallocate memory for a private SQL area and reparse the SQL statement before executing it because RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES.
Nonetheless, when RELEASE_CURSOR=YES, the reparse might
not require extra processing because Oracle caches the parsed
representations of SQL statements and PL/SQL blocks in its Shared SQL Cache. Even if its cursor is closed, the parsed representation remains available until it is aged out of the cache.
The links between a frequently executed SQL statement and its private SQL area should be maintained, because the private SQL area contains all the information needed to execute the statement. Maintaining access to this information makes subsequent execution of the statement much faster.
When HOLD_CURSOR=YES, the link between the cursor and
cursor cache is maintained after Oracle executes the SQL statement.
Thus, the parsed statement and allocated memory remain available. This
is useful for SQL statements that you want to keep active because it
avoids unnecessary reparsing.
When HOLD_CURSOR=YES and RELEASE_CURSOR=NO
(the default), the link between the cache entry and the private SQL area
is maintained after Oracle executes the SQL statement and is not reused
unless the number of open cursors exceeds the value of MAXOPENCURSORS. This is useful for SQL statements that are executed often because the parsed statement and allocated memory remain available.
Using the defaults, HOLD_CURSOR=YES and RELEASE_CURSOR=NO,
after executing a SQL statement with an earlier Oracle version, its
parsed representation remains available. With Oracle database version 7,
under similar conditions, the parsed representation remains available
only until it is aged out of the Shared SQL Cache. Normally, this is not
a problem, but you might get unexpected results if the definition of a
referenced object changes before the SQL statement is reparsed.
shows how HOLD_CURSOR and RELEASE_CURSOR interact. Notice that HOLD_CURSOR=NO overrides RELEASE_CURSOR=NO and that RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES.
Table C-1 HOLD_CURSOR and RELEASE_CURSOR
| HOLD_CURSOR | RELEASE_CURSOR | Links are: |
|---|---|---|
|
NO |
NO |
marked as reusable |
|
YES |
NO |
maintained |
|
NO |
YES |
removed immediately |
|
YES |
YES |
removed immediately |
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26651/viewspace-1040920/ ,如需转载,请注明出处,否则将追究法律责任。