0% found this document useful (0 votes)
58 views

Oracle Query Parsing

Oracle parses SQL statements to check syntax and validity, determine execution path, and optimize performance. It first checks if a statement is already parsed and stored in memory (soft parse) or must undergo full parsing (hard parse). Reducing hard parses improves performance by utilizing existing parses where possible through generic code, bind variables, shared routines, and configuring memory settings like shared pool size.

Uploaded by

Sunish Gopinath
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
58 views

Oracle Query Parsing

Oracle parses SQL statements to check syntax and validity, determine execution path, and optimize performance. It first checks if a statement is already parsed and stored in memory (soft parse) or must undergo full parsing (hard parse). Reducing hard parses improves performance by utilizing existing parses where possible through generic code, bind variables, shared routines, and configuring memory settings like shared pool size.

Uploaded by

Sunish Gopinath
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Parsing in Oracle

Whenever a statement is executed, Oracle follows a methodology to evaluate the statement


in terms of syntax, validity of objects being referred and of course, privileges to the user.
Apart from this, Oracle also checks for identical statements that may have been fired, with
the intention of reducing processing overheads. All this takes place in a fraction of a second,
even less, without the user knowing what is happening to the statement that was fired. This
process is known as Parsing.

Types of Parsing
All statements, DDL or DML, are parsed whenever they are executed. The only key fact is
that whether it was a Soft(statement is already parsed and available in memory) or
aHard (all parsing steps to be carried out) parse. Soft parse will considerably improve the
system performance where as frequent Hard parsing will affect the system. Reducing Hard
parsing will improve the resource utilization and optimize the SQL code.

Parsing process
Oracle internally does the following to arrive at the output of an SQL statement.

1. Syntactical check. The query fired is checked for its syntax.

2. Semantic check. Checks on the validity of the objects being referred in the statement and
the privileges available to the user firing the statement. This is a data dictionary check.

3. Allocation of private SQL area in the memory for the statement.

4. Generating a parsed representation of the statement and allocating Shared SQL area.
This involves finding an optimal execution path for the statement.

In point four, Oracle first checks if the same statement is already parsed and existing in the
memory. If found, the parsed representation will be picked up and the statement executed
immediately (Soft parse). If not found, then the parsed representation is generated and
stored in a shared SQL area (Part of shared pool memory in SGA), the statement is then
executed (Hard parse). This step involves the optimization of the statement, the one that
decides the performance.

Identical statements
Oracle does the following to find identical statements to decide on a soft or a hard parse.

a. When a new statement is fired, a hash value is generated for the text string. Oracle
checks if this new hash value matches with any existing hash value in the shared pool.

b. Next, the text string of the new statement is compared with the hash value matching
statements. This includes comparison of case, blanks and comments present in the
statements.
c. If a match is found, the objects referred in the new statement are compared with the
matching statement objects. Tables of the same name belonging to different a schema will
not account for a match.

d. The bind variable types of the new statement should be of same type as the identified
matching statement.

e. If all of the above is satisfied, Oracle re-uses the existing parse (soft). If a match is not
found, Oracle goes through the process of parsing the statement and putting it in the
shared pool (hard).

Reduce hard parsing

The shared pool memory can be increased when contention occurs, but more
important is that such issues should be addressed at the coding level.
Following are some initiatives that can be taken to reduce hard parsing.

1. Make use of bind variables rather than hard-coding values in your


statements.

2. Write generic routines that can be called from different places. This will
also eliminate code repetition.

3. Even with stringent checks, it may so happen that same statements are
written in different formats. Search the SQL area periodically to check on
similar queries that are being parsed separately. Change these statements
to be look-alike or put them in a common routine so that a single parse can
take care of all calls to the statement.

Identifying unnecessary parse calls at system level

select parse_calls, executions,


substr(sql_text, 1, 300)
from v$sqlarea
where command_type in (2, 3, 6, 7);

Check for statements with a lot of executions. It is bad to have the


PARSE_CALLS value in the above statement close to the EXECUTIONS value.
The above query will fire only for DML statements (to check on other types
of statements use the appropriate command type number). Also ignore
Recursive calls (dictionary access), as it is internal to Oracle.

Identifying unnecessary parse calls at session level

select b.sid, a.name, b.value


from v$sesstat b, v$statname a
where a.name in ('parse count (hard)', 'execute count')
and b.statistic# = a.statistic#
order by sid;

Identify the sessions involved with a lot of re-parsing (VALUE column).


Query these sessions from V$SESSION and then locate the program that is
being executed, resulting in so much parsing.

select a.parse_calls, a.executions, substr(a.sql_text, 1, 300)


from v$sqlarea a, v$session b
where b.schema# = a.parsing_schema_id
and b.sid = <:sid>
order by 1 desc;

The above query will also show recursive SQL being fired internally by
Oracle.

4. Provide enough private SQL area to accommodate all of the SQL


statements for a session. Depending on the requirement, the
parameter OPEN_CURSORS may need to be reset to a higher value. Set
the SESSION_CACHED_CURSORS to a higher value to allow more cursors
to be cached at session level and to avoid re-parsing.

Identify how many cursors are being opened by sessions

select a.username, a.sid, b.value


from v$session a, v$sesstat b, v$statname c
where b.sid = a.sid
and c.statistic# = b.statistic#
and c.name = 'opened cursors current'
order by 3 desc;

The VALUE column will identify how many cursors are open for a session and
how near the count is to the OPEN_CURSORS parameter value. If the margin
is very small, consider increasing the OPEN_CURSORS parameter.

Evaluate cached cursors for sessions as compared to parsing

select a.sid, a.value parse_cnt,


(select x.value
from v$sesstat x, v$statname y
where x.sid = a.sid
and y.statistic# = x.statistic#
and y.name = 'session cursor cache hits') cache_cnt
from v$sesstat a, v$statname b
where b.statistic# = a.statistic#
and b.name = 'parse count (total)'
and value > 0;
The CACHE_CNT ('session cursor cache hits') of a session should be
compared to the PARSE_CNT ('parse count (total)'), if the difference is high,
consider increasing the SESSION_CACHED_CURSORS parameter.

The following parse related information is available in V$SYSSTAT and


V$SESSTAT views, connect with V$STATNAME using STATISTIC# column.

SQL> select * from v$statname where name like '%parse%';

STATISTIC# NAME CLASS


---------- ------------------------- ----------
217 parse time cpu 64
218 parse time elapsed 64
219 parse count (total) 64
220 parse count (hard) 64
221 parse count (failures) 64

5. Shared SQL area may be further utilized for not only identical but also for
some-what similar queries by setting the initialization
parameter CURSOR_SHARING to FORCE. The default value is EXACT. Do
not use this parameter in Oracle 8i, as there is a bug involved with it that
hangs similar query sessions because of some internal processing. If you are
on 9i, try out this parameter for your application in test mode before making
changes in production.

6. Prevent large SQL or PL/SQL areas from ageing out of the shared pool
memory. Ageing out takes place based on Least recently used (LRU)
mechanism. Set the parameter SHARED_POOL_RESERVED_SIZE to a
larger value to prevent large packages from being aged out because of new
entries. A large overhead is involved in reloading a large package that was
aged out.

7. Pin frequent objects in memory using


the DBMS_SHARED_POOL package. This package is created by default. It
can also be created explicitly by running DBMSPOOL.SQL script; this
internally calls PRVTPOOL.PLB script. Use it to pin most frequently used
objects that should be in memory while the instance is up, these would
include procedure (p), functions (p), packages (p) and triggers (r). Pin
objects when the instance starts to avoid memory fragmentation (Even
frequently used data can be pinned but this is a separate topic).

To view a list of frequently used and re-loaded objects

select loads, executions, substr(owner, 1, 15) "Owner",


substr(namespace, 1, 20) "Type", substr(name, 1, 100) "Text"
from v$db_object_cache
order by executions desc;
To pin a package in memory

SQL>exec dbms_shared_pool.keep('standard', 'p');

To view a list of pinned objects

select substr(owner, 1, 15) "Owner",


substr(namespace, 1, 20) "Type",
substr(name, 1, 100) "Text"
from v$db_object_cache
where kept = 'YES';

8. Increasing the shared pool size is an immediate solution, but the above
steps need to be carried out to optimize the database in the long run. The
size of the shared pool can be increased by setting the
parameterSHARED_POOL_SIZE in the initialization file.

Conclusion

Reduce Hard parsing as much as possible! This can be done by writing


generic routines that can be called from different parts of the application,
thus the importance of writing uniform and generic code.

Parsing SQL Statements in Oracle


by Jeff Hunter, Sr. Database Administrator

Contents

1. Overview
2. The Syntax Check & Semantic Analysis
3. Hard Parse vs. Soft Parse
4. Why not Check the Shared Pool First?

Overview

One of the first steps Oracle takes in processing a SQL statement is to parse it. During
the parsing phase, Oracle will break down the submitted SQL statement into its
component parts, determine what type of statement it is (Query, DML, or DDL), and
perform a series of checks on it. Two important concepts for the DBA to understand is
(1) what are the steps involved in the parse phase and (2) what is the difference
between a hard parse and a soft parse. The following figure demonstrates this
sequence of steps.
The Syntax Check & Semantic Analysis

The first two function of the parse phase Syntax Check and Semantic Analysis happen


for each and every SQL statement within the database.

 Syntax Check

Oracle checks that the SQL statement is valid. Does it make sense given
the SQL grammar documented in the SQL Reference Manual? Does it
follow all of the rules for SQL?

 Semantic Analysis

This function of the parse phase, takes the Syntax Check one step further
by checking if the statement is valid in light of the objects in the
database. Do the tables and columns referenced in the SQL statement
actually exist in the database? Does the user executing the statement
have access to the objects and are the proper privileges in place? Are
there ambiguities in the statement? For example, consider a statement
that references two tables emp1 and emp2 and both tables have a
column name. The following statement "select name from emp1, emp
where..." is ambiguous; the query doesn't know which table to
get name from.

Although Oracle considers the first two functions of the parse phase (checking the
validity of the SQL statement and then checking the semantics to ensure that the
statement can be properly executed), the difference is sometimes hard to see from the
users perspective. When Oracle reports an error to the user during the parse phase, it
doesn't just come out and say "Error within the Syntax Function" or "Error within the
Semantics Function".

For example, the following SQL statement fails with a syntax error:
SQL> select from where 4;
select from where 4
*
ERROR at line 1:
ORA-00936: missing expression

Here is an example of a SQL statement that fails with a semantic error:


SQL> select * from table_doesnt_exist;
select * from table_doesnt_exist
*
ERROR at line 1:
ORA-00942: table or view does not exist

Hard Parse vs. Soft Parse

We now consider the next and one of the most important functions of Oracle's parse
phase. The Oracle database now needs to check in the Shared Pool to determine if the
current SQL statement being parsed has already been processed by any other sessions.

If the current statement has already been processed, the parse operation can skip the
next two functions in the process: Optimization and Row Source Generation. If the
parse phase does, in fact, skip these two functions, it is called a soft parse. A soft
parse will save a considerable amount of CPU cycles when running your query. On
the other hand, if the current SQL statement has never been parsed by another session,
the parse phase must execute ALL of the parsing steps. This type of parse is called
a hard parse. It is especially important that developers write and design queries that
take advantage of soft parses so that parsing phase can skip the optimization and row
source generation functions, which are very CPU intensive and a point of contention
(serialization). If a high percentage of your queries are being hard-parsed, your system
will function slowly, and in some cases, not at all.
Oracle uses a piece of memory called the Shared Pool to enable sharing of SQL
statements. The Shared Pool is a piece of memory in the System Global Area (SGA)
and is maintained by the Oracle database. After Oracle completes the first two
functions of the parse phase (Syntax and Semantic Checks), it looks in the Shared
Pool to see if that same exact query has already been processed by another session.
Since Oracle has already performed the semantic check, it has already determined:

 Exactly what table(s) are involved


 That the user has access privileges to the tables.

Oracle will now look at all of the queries in the Shared Pool that have already been
parsed, optimized, and generated to see if the hard-parse portion of the current SQL
statement has already been done.

Why not Check the Shared Pool First?

Now that you understand the steps involved in parsing SQL statements, it's time to
take it one step further. Oracle will always keep an unparsed representation of the
SQL code in the Shared Pool, and that the database will perform a hashing algorithm
to quickly located the SQL code. OK, so why doesn't Oracle make this step (checking
the Shared Pool for a matching statement) the first step in its parsing phase, before
making any other checks.

Even when soft parsing, Oracle needs to parse the statement before it goes looking in
the Shared Pool. One of the big reason's for this sequence is the Semantic Check.
Consider the following query:
select * from emp;

Assume that this query was first submitted by user "SCOTT" and that the "emp" table
in the FROM clause is a table owned by SCOTT. You then submit the same exact
query (as a user other than SCOTT) to Oracle. The database has no idea what "emp" is
a reference to. Is it a synonym to another table? Is it a view in your schema that
references another table? For this reason, Oracle needs to perform a Semantic Check
on the SQL statement to ensure that the code you are submitting is going to reference
the same exact objects you are requesting in your query.

Then remember that Oracle needs to syntactically parse the query before it can
semantically parse it. The hash is good only for finding query strings that are the
same; it doesn't help the database figure out if the referenced statements are the same
statement as in you execution context.

You might also like