Unix Technical Forum

Why woulld a query run with different performance inside/outside of a stored procedure?

This is a discussion on Why woulld a query run with different performance inside/outside of a stored procedure? within the Oracle Database forums, part of the Database Server Software category; --> Puzzled. Usually if I find a slow running query in a stored procedure, I lift it out and run ...


Go Back   Unix Technical Forum > Database Server Software > Oracle Database

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-26-2008, 03:24 AM
Jeremy
 
Posts: n/a
Default Why woulld a query run with different performance inside/outside of a stored procedure?

Puzzled. Usually if I find a slow running query in a stored procedure, I
lift it out and run it in sqlplus or TOAD etc and tune it from there.

Today I am looking at a query which, when declared in a procedure like
this:

for h in (select ......)
loop
..
end loop;

takes 3-4 seconds to parse and execute - i.e. if I stick a trace line
before the "for" and after the "loop" line, the first row becomes
available after 3-4 seconds.

Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
has a pretty good explain plan. The query has one condition based on a
parameter in the plsql procedure which, when run in sqlplus, is replaced
by a constant - other than that the SQL is identical.

Not sure where to start in trying to find the cause of this discrepancy,
would appreciate any pointers.

cheers

--
jeremy

================================================== ==========
ENVIRONMENT:
Oracle 9iR2 / Oracle HTTP Server / mod_plsql / Solaris 8
================================================== ==========
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-26-2008, 03:24 AM
What's in a namespace
 
Posts: n/a
Default Re: Why woulld a query run with different performance inside/outside of a stored procedure?


"Jeremy" <jeremy0505@gmail.com> schreef in bericht
news:MPG.201023bfcb10271b98a3c3@news.individual.ne t...
> Puzzled. Usually if I find a slow running query in a stored procedure, I
> lift it out and run it in sqlplus or TOAD etc and tune it from there.
>
> Today I am looking at a query which, when declared in a procedure like
> this:
>
> for h in (select ......)
> loop
> ..
> end loop;
>
> takes 3-4 seconds to parse and execute - i.e. if I stick a trace line
> before the "for" and after the "loop" line, the first row becomes
> available after 3-4 seconds.
>
> Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
> has a pretty good explain plan. The query has one condition based on a
> parameter in the plsql procedure which, when run in sqlplus, is replaced
> by a constant - other than that the SQL is identical.


You should replace this by a binding variable! See what happens then!

Shakespeare

>
> Not sure where to start in trying to find the cause of this discrepancy,
> would appreciate any pointers.
>
> cheers
>
> --
> jeremy
>
> ================================================== ==========
> ENVIRONMENT:
> Oracle 9iR2 / Oracle HTTP Server / mod_plsql / Solaris 8
> ================================================== ==========



Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-26-2008, 03:24 AM
Jeremy
 
Posts: n/a
Default Re: Why woulld a query run with different performance inside/outside of a stored procedure?

In article <45a619fd$0$335$e4fe514c@news.xs4all.nl>, What's in a
namespace says...
> >
> > Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
> > has a pretty good explain plan. The query has one condition based on a
> > parameter in the plsql procedure which, when run in sqlplus, is replaced
> > by a constant - other than that the SQL is identical.

>
> You should replace this by a binding variable! See what happens then!
>
>


As I understand it bind variables increase efficiency - therefore I
guess the use of a constant in sqlplus shoud, if anything, have a
detrimental impact on performance?

Anyway, done. Same result (i.e. sub 1-second).

DECLARE p_candidate_id NUMBER:=311662;
BEGIN
dbms_output.put_line(TO_CHAR(SYSDATE,'hh24:mi:ss') );
FOR h IN (select ....
LOOP
NULL;
END LOOP;
dbms_output.put_line(TO_CHAR(SYSDATE,'hh24:mi:ss') );
END;

So why should this perform so poorly in the stored procedure versus when
run as a SQL statement or as an anonymous pl/sql block from within a
client tool?

Not actually seeking the answer here but at least an indication of where
I should be looking.

--
jeremy

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-26-2008, 03:24 AM
What's in a namespace
 
Posts: n/a
Default Re: Why woulld a query run with different performance inside/outside of a stored procedure?


"Jeremy" <jeremy0505@gmail.com> schreef in bericht
news:MPG.201030a8b6838e7198a3c4@news.individual.ne t...
> In article <45a619fd$0$335$e4fe514c@news.xs4all.nl>, What's in a
> namespace says...
>> >
>> > Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
>> > has a pretty good explain plan. The query has one condition based on a
>> > parameter in the plsql procedure which, when run in sqlplus, is
>> > replaced
>> > by a constant - other than that the SQL is identical.

>>
>> You should replace this by a binding variable! See what happens then!
>>
>>

>
> As I understand it bind variables increase efficiency - therefore I
> guess the use of a constant in sqlplus shoud, if anything, have a
> detrimental impact on performance?
>
> Anyway, done. Same result (i.e. sub 1-second).
>
> DECLARE p_candidate_id NUMBER:=311662;
> BEGIN
> dbms_output.put_line(TO_CHAR(SYSDATE,'hh24:mi:ss') );
> FOR h IN (select ....
> LOOP
> NULL;
> END LOOP;
> dbms_output.put_line(TO_CHAR(SYSDATE,'hh24:mi:ss') );
> END;
>
> So why should this perform so poorly in the stored procedure versus when
> run as a SQL statement or as an anonymous pl/sql block from within a
> client tool?
>
> Not actually seeking the answer here but at least an indication of where
> I should be looking.
>
> --
> jeremy
>


Sorry, Jeremy, I read your post the wrong way around. But still I think you
should use a bind variable in SQLPLUS (select ... from ... where column_x=
:A) in stead of a contant to compare the performance. But I have no further
indication for clues...

Shakespeare


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-26-2008, 03:25 AM
Charles Hooper
 
Posts: n/a
Default Re: Why woulld a query run with different performance inside/outside of a stored procedure?

Jeremy wrote:
> Puzzled. Usually if I find a slow running query in a stored procedure, I
> lift it out and run it in sqlplus or TOAD etc and tune it from there.
>
> Today I am looking at a query which, when declared in a procedure like
> this:
>
> for h in (select ......)
> loop
> ..
> end loop;
>
> takes 3-4 seconds to parse and execute - i.e. if I stick a trace line
> before the "for" and after the "loop" line, the first row becomes
> available after 3-4 seconds.
>
> Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
> has a pretty good explain plan. The query has one condition based on a
> parameter in the plsql procedure which, when run in sqlplus, is replaced
> by a constant - other than that the SQL is identical.
>
> Not sure where to start in trying to find the cause of this discrepancy,
> would appreciate any pointers.
>
> cheers
>
> --
> jeremy
>
> ================================================== ==========
> ENVIRONMENT:
> Oracle 9iR2 / Oracle HTTP Server / mod_plsql / Solaris 8
> ================================================== ==========


Interesting article:
http://www.oracle.com/technology/tec...atures_Doc.pdf

"3.2. BULK BINDING IN NATIVE DYNAMIC SQL 3.2.1. DEFINING
Consider a program to populate elements of a PL/SQL collection from a
SELECT query thus...

declare
type employee_ids_t is table of employees.employee_id%type index by
binary_integer;
employee_ids employee_ids_t;
n integer:=0;
begin
for j in ( select employee_id from employees where salary < 3000 )
loop
n := n+1;
employee_ids(n) := j.employee_id;
end loop;
end;

Each explicit row by row assignment of the collection element to the
cursor component causes a context switch between the PL/SQL engine and
the SQL engine resulting in performance overhead. The following
formulation (one of a family of constructs generically referred to as
bulk binding and available pre-Oracle9i)...

begin
select employee_id
bulk collect into employee_ids
from employees where salary < 3000;
end;

...substantially improves performance by minimizing the number of
context switches required to execute the block. (The above fragments
work pre-Oracle 9i.)"

The above is possibly one explanation - cost of context switching.

Predicted cardinality (expected number of rows that will be returned)
is another possibility - a 10053 trace would tell if this is the case.
When bind variables are used, the predicted cardinality will be 5% of
the rows. The predicted cardinality rules change if constants
(literals) are used, and change again if histograms are present.
Changes in the predicted cardinality can change the execution plan,
possibly to a less efficient one. This is a second possible
explanation.

When bind variables are used, Oracle 9i is permitted to peek at the
bind variables on the initial hard parse (it seems that there may be an
opportunity for Oracle to peek at the bind variables on every execution
if CURSOR_SHARING is set to SIMILAR, but there are warnings about using
this setting in the "Cost-Based Oracle Fundamentals" book). So, if
atypical values were used for the bind variable values during the
initial hard parse, future executions of the SQL statement with typical
values could suffer from an inefficient execution plan. If the two SQL
statements (one executed in PL/SQL and the other in SQLPlus) differ by
even a single space, they are not considered the same SQL statement,
and a hard parse will be required. This is a third possible
explanation.

If CURSOR_SHARING is set to FORCE, constants (literals) will be
automatically replaced with bind variables. If the two SQL statements
(one executed in PL/SQL and the other in SQLPlus) differ by even a
single space, they are not considered the same SQL statement, and a
hard parse will be required. Thus, the two SQL statements may have
different execution plans. This is a fourth possible explanation.

There must be more possible explanations.

Charles Hooper
PC Support Specialist
K&M Machine-Fabricating, Inc.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-26-2008, 03:25 AM
=?utf-8?q?Lothar_Armbr=C3=BCster?=
 
Posts: n/a
Default Re: Why woulld a query run with different performanceinside/outside of a stored procedure?

Jeremy <jeremy0505@gmail.com> writes:

> Puzzled. Usually if I find a slow running query in a stored procedure, I
> lift it out and run it in sqlplus or TOAD etc and tune it from there.
>
> Today I am looking at a query which, when declared in a procedure like
> this:
>
> for h in (select ......)
> loop
> ..
> end loop;
>
> takes 3-4 seconds to parse and execute - i.e. if I stick a trace line
> before the "for" and after the "loop" line, the first row becomes
> available after 3-4 seconds.
>
> Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
> has a pretty good explain plan. The query has one condition based on a
> parameter in the plsql procedure which, when run in sqlplus, is replaced
> by a constant - other than that the SQL is identical.
>
> Not sure where to start in trying to find the cause of this discrepancy,
> would appreciate any pointers.
>


Hello Jeremy,

IIRC Oracle uses different optimizer parameters in PL/SQL.
I think in PL/SQL Oracle uses ALL_ROWS whereas in SQL*Plus
FIRST_ROWS is used. Maybe you found a query the differs in execution plan
with these optimizer settings.
Have a look on optimizer hints to see how you could use the same settings
in SQL*Plus as in PL/SQL.
I saw some queries the performed better with FIRST_ROWS hint.

Hope that helps,
Lothar

--
Lothar Armbrüster | lothar.armbruester@t-online.de
Hauptstr. 26 |
65346 Eltville |
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 02-26-2008, 03:27 AM
bdurrettccci@yahoo.com
 
Posts: n/a
Default Re: Why woulld a query run with different performance inside/outside of a stored procedure?

I would do a 10046 trace if you can. That will show you what it is
spending its time on. You could tkprof it also with waits=yes.

- Bobby

Jeremy wrote:
> Puzzled. Usually if I find a slow running query in a stored procedure, I
> lift it out and run it in sqlplus or TOAD etc and tune it from there.
>
> Today I am looking at a query which, when declared in a procedure like
> this:
>
> for h in (select ......)
> loop
> ..
> end loop;
>
> takes 3-4 seconds to parse and execute - i.e. if I stick a trace line
> before the "for" and after the "loop" line, the first row becomes
> available after 3-4 seconds.
>
> Lifting the SQL out and running in sqlplus, it takes < 0.5 seconds and
> has a pretty good explain plan. The query has one condition based on a
> parameter in the plsql procedure which, when run in sqlplus, is replaced
> by a constant - other than that the SQL is identical.
>
> Not sure where to start in trying to find the cause of this discrepancy,
> would appreciate any pointers.
>
> cheers
>
> --
> jeremy
>
> ================================================== ==========
> ENVIRONMENT:
> Oracle 9iR2 / Oracle HTTP Server / mod_plsql / Solaris 8
> ================================================== ==========


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:47 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com