Skip to Main Content
  • Questions
  • 7 stages a query goes through before retrieving the rows

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Omer.

Asked: September 08, 2001 - 10:28 am UTC

Last updated: July 05, 2011 - 7:53 am UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

Tom

I heard that there are 7 stages a query goes through before retrieving the rows. Can you explain to us what are those 7 stages.
I can think of parsing the query, fetching the rows etc.

can you discuss this with us.


Omer

and Tom said...

Never heard of "7 stages".

there are 8 STEPS i can think of (this is would you would do in pure dynamic sql to execute a query -- similar to what SQLPlus goes through)

1) prepare
2) optional describe
3) bind INPUTS (if any)
4) optional describe outputs
5) define OUTPUTS
6) open
7) fetch
8) close


Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

exciting

A reader, September 08, 2001 - 6:44 pm UTC

Tom

Can you put in a few sentences for each of the stages you have described.(if you can take an example and explain that would be wonderful)

Tom Kyte
September 08, 2001 - 7:15 pm UTC

Sure, we'll work with the query "select ename from emp where empno = :empno"

1) prepare. That parses/compiles the query. If the query was syntactically invalid, you did not have access to the objects, etc -- it would fail.

2) describe. In languages like Pro*C this would fill in a data structure that describes all of the INPUTS to the query. In this case, the data structure would say "I see :empno as a bind variable". It would tell us of one bind variable

3) bind INPUTS. In this step -- you would provide to us the value of :empno

4) describe outputs. In this step, you ask us "what output might this query result in". In this case we would say "there is one column, it is named ENAME, it is a varchar2(10)".

5) define outputs. Here you would tell us "where" to put the value of ename and what datatype you would like to use. In the prior step we told you this was a varchar2(10) -- you tell us what datatype you would like to fetch this into. This makes more sense when you fetch a number/date -- you can tell us to put the results into a STRING type instead and we'll convert the number/date into a string for you.

6) open. This "executes" the query. It just opens the result set. In most cases -- this is instantaneous (we do not answer the query here -- that happens in the FETCH phase)

7) fetch. Get the data, fetch the rows

8) close. finish up, close the cursor (if you won't be using it again in this application). releases all resources.

MY rating -- **********************, absolutely useful

A reader, September 09, 2001 - 10:26 am UTC

Have you covered this anywhere in your book.

Tom Kyte
September 09, 2001 - 10:50 am UTC

Chapter 16, Dynamic SQL.

I cover only PLSQL dynamic sql which does not support step #2 below (describe the INPUTS -- bind variables ). Otherwise all of the steps are covered in detail there.

In order to get the bind variable names (inputs) from a query in PLSQL you must parse the query text yourself.

function get_binds( p_stmt in varchar2 ) return dbms_sql.varchar2_table
as
l_binds dbms_sql.varchar2_table;
l_in_literal boolean default false;
l_ch varchar2(1);
i number default 1;
l_str varchar2(255);
l_add boolean;
begin
loop
exit when ( i > length(p_stmt) );
l_ch := substr( p_stmt, i, 1 );

if ( l_ch = '''' )
then
l_in_literal := NOT l_in_literal;
elsif ( l_ch = '-' AND substr(p_stmt,i+1,1) = '-' )
then
i := nvl(instr( p_stmt, chr(10), i ),0);
if ( i = 0 ) then i := length(p_stmt); end if;
elsif ( l_ch = '/' AND substr(p_stmt,i+1,1) = '*' )
then
i := nvl(instr( p_stmt, '*/', i ),0);
if ( i = 0 ) then i := length(p_stmt); end if;
end if;

if ( l_ch = ':' and NOT l_in_literal )
then
l_str := ':';
for j in i+1 .. length(p_stmt)
loop
l_ch := upper(substr( p_stmt, j, 1 ));
exit when l_ch not between '0' and '9'
AND l_ch not between 'A' and 'Z'
AND l_ch <> '_';
l_str := l_str || upper(l_ch);
i := j;
end loop;
l_add := (length(l_str) > 1);
for k in 1 .. l_binds.count
loop
if ( l_binds(k) = l_str )
then
l_add := false;
exit;
end if;
end loop;
if ( l_add )
then
l_binds(l_binds.count+1) := l_str;
end if;
end if;
i := i+1;
end loop;

return l_binds;
end get_binds;

Omer

Omer, September 09, 2001 - 6:55 pm UTC

where do the above 8 stages occur in the following layers.
can you kindly put a few sentences for each of the above layer and explain to us in simple terms.

1.The oracle call interface
2.the user program interface
3.The oracle program interface
4.The compilation layer
5.The execution layer
6.The distributed execution layer
7.The network execution layer
8.The security layer
9.The query layer
10.The recursive program interface
11.The access layer
12.The data layer
13.The transaction layer
14.The cache layer
15.The services layer
16.The lock management layer
17.The generic layer
18.The operating system dependencies

(Is understanding the above layers very important to understand oracle)

Tom Kyte
September 09, 2001 - 7:13 pm UTC

It doesn't make sense to map the phases of procedurally executing a query with the above layers. I'll make a couple of comments

- OCI, isn't really a layer, it is an API. You could use OCI to prepare, bind, define, open, fetch, etc -- but it is not a "layer". Its like ODBC or JDBC - just an API

- UPI & OPI, user/oracle program interface, are more APIs -- they are the lowest level API but just API's none the less.

Many of the remaining items in your list will apply -- perhaps at many times. A statement will be compiled during a parse -- but that statement might contain a call to a plsql function that does dynamic selects itself. So, a FETCH from that statement might hit the compile "layer" as well. Normally parse = compile.

There is no straightforward, one to one mapping. In my opinion, it is not very important in day to day operations to understand these layers.

Bhagat Singh

Bhagat Singh, September 10, 2001 - 12:04 am UTC

Knowing better the software helps in getting better results

Thanks a lot;

Ashraf Jebreel, September 10, 2001 - 12:48 am UTC

This is exactly what I was looking for. Today I am browsing just to submit the same question;

Thanks a lot.

I was talking of the below 7 steps

Omer, September 10, 2001 - 10:31 am UTC

Does your 8 steps fall under these 7 steps

( the below info is provided by oracle itself, and by the way what is "heuristics")

Query processing can be divided into 7 phases:
[1] Syntactic - checks the syntax of the query
[2] Semantic - checks that all objects exist and are
accessible
[3] View Merging - rewrites query as join on base tables as
opposed to using views
[4] Statement Transformation - rewrites query transforming some complex constructs into simpler ones where appropriate (e.g. subquery merging, in/or
transformation)
[5] Optimization - determines the optimal access path for the
query to take. With the Rule Based Optimizer (RBO) it uses a set of heuristics
to determine access path. With the Cost Based Optimizer (CBO) we use statistics to analyze the relative costs of accessing objects.
[6] QEP Generation
[7] QEP Execution
(QEP = Query Evaluation Plan)

Steps [1]-[6] are handled by the parser.
Step [7] is the execution of the statement.


( can you give an example for point number 4 , and discuss)





Tom Kyte
September 10, 2001 - 11:10 am UTC

You know, if you have the seven steps -- it would be helpful to put them in in the first place (less guessing on my part).

1, 2, 3, 4, 5, 6 are all part of PARSE.
7 is part of fetch or execute (execute is what you do to an UPDATE for example)
You led me to believe with your question that you had "heard there were 7 stages" but didn't know what they were.

the dictionary definition of heuristic is:

Main Entry: heu·ris·tic
Pronunciation: hyu-'ris-tik
Function: adjective

Etymology: German heuristisch, from New Latin heuristicus, from Greek heuriskein to discover; akin to Old Irish fo-fúair he found
Date: 1821

: involving or serving as an aid to learning, discovery, or problem-solving by experimental and especially trial-and-error methods <heuristic techniques> <a heuristic assumption>; also : of or relating to exploratory problem-solving techniques that utilize self-educating techniques (as the evaluation of feedback) to improve performance <a heuristic computer program>
................

Simply put, it is the set of rules followed by the software to optimize your query. RBO uses rules (heuristics) built into it. The CBO does not.


An example of [4] would be the fact that:

select * from t where x in ( 1, 2, 3 )

is actually rewritten as

select * from t where ( x = 1 or x = 2 or x = 3 )

before being processed. A much mnore complex case could be a materialized view, such as:

create materialized view emp_rollup
enable query rewrite
as
select deptno, sum(sal) sal
from emp
group by deptno;


Now, given that all the necessary settings have been done (see
the data warehousing guide for a comprehensive example) your end
users can query:

select deptno, sum(sal) from emp where deptno in ( 10, 20)
group by deptno;

and the database engine will rewrite the query to go against the
precomputed rollup, not the details -- giving you the answer in
a fraction of the time it would normally take (depending on the volume of data of course).




Learning something on every thread

J, September 10, 2001 - 2:39 pm UTC

Sorry to extend this further but ::

You said
"
An example of [4] would be the fact that:

select * from t where x in ( 1, 2, 3 )

is actually rewritten as

select * from t where ( x = 1 or x = 2 or x = 3 )

before being processed.
"

Would "in ( 1, 2, 3 )" be better written "( x = 1 or x = 2 or x = 3 )" as far as processing overhead goes?
Is this something to even consider?

Tom Kyte
September 10, 2001 - 2:55 pm UTC

No, I would not consider this. The rewrite happens on a hard parse only and happens so fast -- I would not even consider it. In fact, depending on the optimizer mode, the rewrite might not take place (i should have mentioned that in the last comment). For example (assuming an index on empno)

scott@ORA817DEV.US.ORACLE.COM> select empno from emp where empno in ( 1,2,3,4 );

Execution Plan
----------------------------------------------------------
SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=4 Bytes=12)
INDEX (FAST FULL SCAN) OF 'EMP_PK' (UNIQUE) (Cost=1 Card=4 Bytes=12)

scott@ORA817DEV.US.ORACLE.COM> select /*+ FIRST_ROWS */ empno from emp where empno in ( 1,2,3,4 );

Execution Plan
----------------------------------------------------------
SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=8 Card=4 Bytes=12)
INLIST ITERATOR
INDEX (RANGE SCAN) OF 'EMP_PK' (UNIQUE) (Cost=8 Card=4 Bytes=12)

Here the query was NOT rewritten with the CBO, the CBO instead tends to use the INLIST ITERATOR to "loop over" the values in an IN LIST


Use "where x in ( ..... )" when you have a list. If need be, it'll be rewritten.

The get_binds breaks if I use double quote to specify bind variables

Hui Li, September 24, 2003 - 8:36 pm UTC

Please see the following example

select * from ams_test_char where msg = : " this is a test "

If I use DBMS_SQL to parse it, it is fine but your API can not work with this query

Tom Kyte
September 25, 2003 - 5:14 am UTC

"fix it"

should not be really hard.

Open and fetch phases

Arun Gupta, April 16, 2004 - 9:55 am UTC

Tom,
I am still not clear as to what happens in the open phase of query processing. We can assume dedicated server. As you said, the query executes in open phase but the rows are returned during the fetch phase.
a) Does this mean that the Oracle server process starts reading the data from buffer cache and/or datafiles and does all the sorting etc. in fetch phase?
b) Does Oracle server process acquires object locks during open phase or earlier?
c) Are the open and fetch phases in query processing loosely analogous to open and fetch statements in cursor processing?

Thanks...

Tom Kyte
April 16, 2004 - 10:16 am UTC

a) USUALLY -- almost always, yes.

b) it gets some parse locks and for DML that modifies (eg: select for update), it'll get actual data locks during open.

c) not only loosely, they are one in the same.

Debojyoti Roy, July 02, 2011 - 11:24 pm UTC

Sir,

I have a question that , in soft parse what are the stpes are followed .

I hope, In hard parse above mentioned 8 steps are followed .

Thanks
Debojyoti
Tom Kyte
July 05, 2011 - 7:53 am UTC

they are identical, all 8.

the prepare phase is done under the covers a little different, but you yourself still always do all 8 steps.