You are on page 1of 8

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.

If all of the above is satisfied. the objects referred in the new statement are compared with the matching statement objects. executions. v$statname a where a. but more important is that such issues should be addressed at the coding level. Oracle goes through the process of parsing the statement and putting it in the shared pool (hard).c. It is bad to have the PARSE_CALLS value in the above statement close to the EXECUTIONS value. 2. 3. Identifying unnecessary parse calls at system level select parse_calls. it may so happen that same statements are written in different formats. b. Tables of the same name belonging to different a schema will not account for a match. Make use of bind variables rather than hard-coding values in your statements. 6. as it is internal to Oracle. 7). If a match is found. Even with stringent checks. The above query will fire only for DML statements (to check on other types of statements use the appropriate command type number). If a match is not found. 1. substr(sql_text. Search the SQL area periodically to check on similar queries that are being parsed separately. Identifying unnecessary parse calls at session level select b.name in ('parse count (hard)'. Write generic routines that can be called from different places. Check for statements with a lot of executions. Reduce hard parsing The shared pool memory can be increased when contention occurs. 1. 300) from v$sqlarea where command_type in (2. 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. a.value from v$sesstat b.name. d.sid. 'execute count') . This will also eliminate code repetition. e. 3. Oracle re-uses the existing parse (soft). The bind variable types of the new statement should be of same type as the identified matching statement. Also ignore Recursive calls (dictionary access). Following are some initiatives that can be taken to reduce hard parsing.

a.name = 'parse count (total)' and value > 0.sid = <:sid> by 1 desc.statistic# and y. v$session b b.sid c.statistic# = x.name = 'opened cursors current' by 3 desc. Set the SESSION_CACHED_CURSORS to a higher value to allow more cursors to be cached at session level and to avoid re-parsing. b. Provide enough private SQL area to accommodate all of the SQL statements for a session. 300) v$sqlarea a.sid = a.sql_text. . a. substr(a. the parameter OPEN_CURSORS may need to be reset to a higher value. The above query will also show recursive SQL being fired internally by Oracle.sid and y.statistic# = b. Depending on the requirement. v$sesstat b. If the margin is very small. Identify the sessions involved with a lot of re-parsing (VALUE column).statistic# = a.username.sid. v$statname b where b. (select x. consider increasing the OPEN_CURSORS parameter.schema# = a. select from where and order a. v$statname c b.sid = a. 1.value v$session a. Evaluate cached cursors for sessions as compared to parsing select a. Query these sessions from V$SESSION and then locate the program that is being executed. v$statname y where x.parse_calls.statistic# order by sid.statistic# = a.statistic# and b.parsing_schema_id b.sid. a.executions. resulting in so much parsing.value parse_cnt.statistic# c.and b.value from v$sesstat x. 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. Identify how many cursors are being opened by sessions select from where and and order a.name = 'session cursor cache hits') cache_cnt from v$sesstat a. 4.

A large overhead is involved in reloading a large package that was aged out. The default value is EXACT. substr(owner. If you are on 9i. 1. these would include procedure (p). substr(name. 6. Pin objects when the instance starts to avoid memory fragmentation (Even frequently used data can be pinned but this is a separate topic). 100) "Text" from v$db_object_cache order by executions desc. packages (p) and triggers (r). 7.The CACHE_CNT ('session cursor cache hits') of a session should be compared to the PARSE_CNT ('parse count (total)'). 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. consider increasing the SESSION_CACHED_CURSORS parameter. this internally calls PRVTPOOL. Use it to pin most frequently used objects that should be in memory while the instance is up. executions. It can also be created explicitly by running DBMSPOOL. 20) "Type". functions (p). 1. Pin frequent objects in memory using the DBMS_SHARED_POOL package. This package is created by default. connect with V$STATNAME using STATISTIC# column.---------parse time cpu 64 parse time elapsed 64 parse count (total) 64 parse count (hard) 64 parse count (failures) 64 5. STATISTIC# ---------217 218 219 220 221 NAME CLASS ------------------------.PLB script. substr(namespace. Ageing out takes place based on Least recently used (LRU) mechanism. Prevent large SQL or PL/SQL areas from ageing out of the shared pool memory. The following parse related information is available in V$SYSSTAT and V$SESSTAT views. Do not use this parameter in Oracle 8i. 15) "Owner". Set the parameter SHARED_POOL_RESERVED_SIZE to a larger value to prevent large packages from being aged out because of new entries. SQL> select * from v$statname where name like '%parse%'. 1. try out this parameter for your application in test mode before making changes in production. . if the difference is high. To view a list of frequently used and re-loaded objects select loads. as there is a bug involved with it that hangs similar query sessions because of some internal processing.SQL script.

DML. 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. The size of the shared pool can be increased by setting the parameterSHARED_POOL_SIZE in the initialization file.keep('standard'. 100) "Text" from v$db_object_cache where kept = 'YES'. thus the importance of writing uniform and generic code. but the above steps need to be carried out to optimize the database in the long run. 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. During the parsing phase. Increasing the shared pool size is an immediate solution.To pin a package in memory SQL>exec dbms_shared_pool. substr(name. To view a list of pinned objects select substr(owner. 1. substr(namespace. The following figure demonstrates this sequence of steps. 1. Sr. Database Administrator Contents 1. 4. Overview The Syntax Check & Semantic Analysis Hard Parse vs. 2. 'p'). 20) "Type". Soft Parse Why not Check the Shared Pool First? Overview One of the first steps Oracle takes in processing a SQL statement is to parse it. 15) "Owner". or DDL). and perform a series of checks on it. 1. 8. Parsing SQL Statements in Oracle by Jeff Hunter. 3. determine what type of statement it is (Query. Oracle will break down the submitted SQL statement into its component parts. .

takes the Syntax Check one step further by checking if the statement is valid in light of the objects in the database.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. consider a statement that references two tables emp1 and emp2 and both tables have a . Does it make sense given the SQL grammar documented in the SQL Reference Manual? Does it follow all of the rules for SQL? y Semantic Analysis This function of the parse phase. y Syntax Check Oracle checks that the SQL statement is valid. 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.

If the current statement has already been processed." is ambiguous. If a high percentage of your queries are being hard-parsed. the following SQL statement fails with a syntax error: SQL> select from where 4. The following statement "select name from emp1. When Oracle reports an error to the user during the parse phase. This type of parse is called a hard parse. which are very CPU intensive and a point of contention (serialization). For example.. . the parse operation can skip the next two functions in the process: Optimization and Row Source Generation.. not at all. 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. select * from table_doesnt_exist * ERROR at line 1: ORA-00942: table or view does not exist Hard Parse vs. the query doesn't know which table to get name from. If the parse phase does. your system will function slowly. On the other hand. it doesn't just come out and say "Error within the Syntax Function" or "Error within the Semantics Function". it is called a soft parse. if the current SQL statement has never been parsed by another session. 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. the parse phase must execute ALL of the parsing steps. the difference is sometimes hard to see from the users perspective. skip these two functions.column name. 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). in fact. emp where. and in some cases. 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. A soft parse will save a considerable amount of CPU cycles when running your query.

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. Oracle needs to parse the statement before it goes looking in the Shared Pool. After Oracle completes the first two functions of the parse phase (Syntax and Semantic Checks). and that the database will perform a hashing algorithm to quickly located the SQL code. it has already determined: y y Exactly what table(s) are involved That the user has access privileges to the tables. Even when soft parsing. Then remember that Oracle needs to syntactically parse the query before it can semantically parse it. Since Oracle has already performed the semantic check. Oracle will now look at all of the queries in the Shared Pool that have already been parsed. The Shared Pool is a piece of memory in the System Global Area (SGA) and is maintained by the Oracle database. One of the big reason's for this sequence is the Semantic Check. so why doesn't Oracle make this step (checking the Shared Pool for a matching statement) the first step in its parsing phase. Oracle will always keep an unparsed representation of the SQL code in the Shared Pool. Why not Check the Shared Pool First? Now that you understand the steps involved in parsing SQL statements. The database has no idea what "emp" is a reference to. . OK. it doesn't help the database figure out if the referenced statements are the same statement as in you execution context. it looks in the Shared Pool to see if that same exact query has already been processed by another session. You then submit the same exact query (as a user other than SCOTT) to Oracle. before making any other checks. Consider the following query: select * from emp. 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.Oracle uses a piece of memory called the Shared Pool to enable sharing of SQL statements. The hash is good only for finding query strings that are the same. and generated to see if the hard-parse portion of the current SQL statement has already been done. it's time to take it one step further. optimized. Is it a synonym to another table? Is it a view in your schema that references another table? For this reason.