You are on page 1of 4

Process of Executing SQL Statements

(See Also:Oracle® Database Concepts 10g Release 2 (10.2)||Chapter

24  SQL, PL/SQL, and Java)

Understanding the Process of Executing SQL Statements


In order to be effective at tuning SQL statements, the database professional

must have an intimate understanding of how the SQL is transformed from the
original source code into an executable form. At a high level, SQL processing
is broken down into several steps:

1. Parsing the source code to locate any syntax errors

2. Invoking the SQL optimizer to derive an execution plan
3. Create and run an executable, based on the execution plan
4. Fetching the results set from the database and return it to the calling

Oracle has a special RAM memory region within the System Global Area
(SGA) to process SQL statements. Most relational databases contain multiple
areas of RAM caches:

1. RAM cache for data blocks

2. RAM cache for SQL statements
3. RAM for caching the data dictionary
4. RAM for caching program execution code

Just as the data caches within a relational database use a most frequently
used algorithm to cache data blocks that are frequently referenced, the
Oracle database provides a special cache called library cache to store
frequently executed SQL statements.

Every time an SQL statements enters the Oracle system, Oracle begins by
looking to see if the SQL statement has already been processed. Oracle does
this by invoking a hashing algorithm, using the SQL statement as input, and
goes to the RAM address to see if the SQL statement has already been
parsed. If the statement has already been parsed, Oracle grabs the
executable and immediately re-executes the program, at the same time
incrementing the executions column in the v$sql view.

In order to make effective use of the library cache, it is important for the
Oracle database professional to ensure that all of the SQL in the library cache
is fully reentrant. By fully reentrant, we mean that the SQL is free of literal
variables, such that the SQL can be re-executed using different bind variables
as input. For example, the following code would not be considered reentrant
because of the embedded literal.
select * from customer where name = ‘BURLESON’;

To make this SQL reentrant, we can replace the literals within the SQL
statement with a bind variable, thereby making the SQL fully re-entrant, and

select * from customer where name = ‘:var1’;

To facilitate this type of literal substitution, Oracle provides a tool called

cursor_sharing. Setting cursor_sharing=force automates the process of
substituting out literal values within SQL statements. This is very important
tool to those Oracle database administrators whose vendor applications
generate dynamic SQL that contains literal values.

The best way to locate and tune Oracle SQL statements is by extracting the
SQL directly from Oracle's library cache. The v$sql and v$sql_plan views can
be used to allow the immediate extraction of SQL statements from the library
cache. Further, the v$sql_plan view can tell us valuable information about
the access patterns of the SQL that are currently within the library cache.

We have to note that the process speed of executing SQL statements can be
very quick, and tens of thousands of SQL statements can be executed every
minute in a busy Oracle database. Hence, we need some kind of a
monitoring tool that will tell us to salient characteristics of SQL activity over
fixed periods of time. We use the Oracle STATSPACK utility for this purpose
and part of your reading assignments will be to understand how we can use
STATSPACK to monitor the behavior all the library cache and see the behavior
of individual SQL statements over time.

What happens when Oracle processes an SQL Statement?


An SQL statement must always be parsed. Then, it can be executed

any number of times. If it is a select statement, the result-data needs be
fetched for each execution.

One of the goals of the parse phase is to generate a query execution
plan (QEP). Does the statement correspond to an open cursor, ie, does the
statement already exist in the library cache. If yes, the statement needs not
be parsed anymore and can directly be executed.
If the cursor is not open, it might still be that it is cached in the cursor cache.
If yes, the statement needs not be parsed anymore and can directly be
If not, the statement has to be verified syntactically and semantically:
This step checks if the syntax of the statmenet is correct. For example,
a statement like select foo frm bar is syntactically not correct (frm instead of

A statement might be invalid even if the syntax is correct. For example
select foo from bar is invalid if there is no table or view named bar, or if there
is such a table, but without a column named foo.
Also, the table might exist, but the user trying to execute the query does not
have the necessary object privileges.
If the statement is syntactically and semantically correct, it is placed into the
library cache (which is part of the Shared Pool).

A cursor is just a handle to a DML statement. You need a cursor to
execute any DML in Oracle - be it an insert/update/delete/select whatever.

It is just a "handle", sort of like opening a file. Think of a select statement like
"open file". Once you open the file, you can read from it, once you
execute the cursor - you can read from it.

Opening the cursor

A cursor for the statement is opened. The statement is hashed and
compared with the hashed values in the sql area. If it is in the sql area, it is a
soft parse, otherwise, it's a hard parse.
Only in the case of a hard parse, the statement undergoes the following steps
(view merging, statement transformation, optimization)

View merging
If the query contains views, the query might be rewritten to join the
view's base tables instead of the views.

Statement Transformation
Transforms complex statements into simpler ones through subquery
unnesting or in/or transformations

The CBO uses "gathered??" statistics to minimize the cost to execute
the query. The result of the optimization is the query evaluation plan (QEP). If
bind variable peeking is used, the resulting execution plan might be
dependant on the first bound bind-value.

Memory for bind variables is allocated and filled with the actual bind-
values. The execution plan is executed.
Oracle checks if the data it needs for the query are already in the buffer
cache. If not, it reads the data off the disk into the buffer cache.
The record(s) that are changed are locked. No other session must be able to
change the record while they're updated. Also, before and after images
describing the changes are written to the redo log buffer and the rollback
segments. The original block receives a pointer to the rollback segment.
Then, the data is changed.

Data is fetched from database blocks. Rows that don't match the
predicate are removed. If needed (for example in an order by statement),
the data is sorted. The data is then returned to the application.

The execution plan

The query execution plan is also stored in the library cache. EXPLAIN PLAN
can be used to see how the statement is executed.

Private SQL Area

Each session that issues an SQL statement has a private SQL area associated
with this statement. The first step for Oracle when it executes an SQL
statement is to establish a run time area (within the private SQL area) for the

Tuning SQL statements

dbms_sqltune, statspack