Home » RDBMS Server » Performance Tuning » How to Change execution plan of Currently Executing Statement? (Oracle 10.2.4.0 on RHEL)
How to Change execution plan of Currently Executing Statement? [message #493500] Tue, 08 February 2011 08:32 Go to next message
OraKaran
Messages: 183
Registered: March 2008
Location: United Kingdom
Senior Member
Hello

Please refer following sql statements and code

Session 1
create table tab1 as select * from dba_objects where object_id is not null;

alter session set events '10046 trace name context forever, level 12';


declare
x number;
begin
for i in 1..4
loop
select count(1) into x from tab1 where object_id=2331;
--dbms_output.put_line(i);
insert into tab2 values(i);
commit;
dbms_lock.sleep(6);
end loop;
end;
/



Session 2
after "starting" the above pl/sql block from Session 1, I keep on querying tab2 from Session 2
And as soon as 2 records are inserted in tab2, I create index from Session 2

select * from tab2;
select * from tab2;
select * from tab2;

         N
----------
         1
         2
create index i on tab1(object_id);



As I have tested from a single session (just before this test) such index is used for the sql statement
select count(1) into x from tab1 where object_id=2331;


However when I checked the trace file I am not geeting results as expected

I am expecting 4 execution plans - 2 FTS and 2 Index Access scans
and for this I am issuing following command

tkprof dst1_ora_7369.trc dst1_ora_7369.txt aggregate=no sys=no


But unfortunately I am getting following output

SELECT COUNT(1)
FROM
 TAB1 WHERE OBJECT_ID=2331


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      4      0.00       0.00          0          2          0           0
Fetch        4      0.03       0.03          0       1646          0           4
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        9      0.03       0.03          0       1649          0           4

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 5     (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
      2  SORT AGGREGATE (cr=4 pr=0 pw=0 time=73 us)
      2   INDEX RANGE SCAN I (cr=4 pr=0 pw=0 time=47 us)(object id 4673976)


Note : Complete trace file is attached with this post

My questions are
1) Why I am unable to see 4 execution plans - 2 with FTS and 2 with Index access when I mentioned 'aggregate=no'?
2) Whether the index i will be used for last 2 iterations after first 2 iterations of FTS?

If answer to above question 2) is 'No'
By which method I can force an ongoing sql statement in loop to take different execution path?
Of course I can't hard parse sql in 'that' current session
Will flushing Shared pool help in above case?

Thanks and Regards,
OraKaran
Re: How to Change execution plan of Currently Executing Statement? [message #493511 is a reply to message #493500] Tue, 08 February 2011 09:06 Go to previous messageGo to next message
hkchital
Messages: 128
Registered: September 2008
Location: Singapore
Senior Member
The Row Source Operations shows that the Index was used -- at least in the fourth execution if not the third one as well.
Unfortunately, the SQL statistics are for all 4 exectuions (and that is why consistent gets shows up as 1,646 blocks while the Index Read plan did only 4 blocks). So the first 2 (or 3 ?) executions did do a FullTableScan while the last 2 or 1 did do an IndexRangeScan.

Apparently, "aggregate=NO" did not kick in at all.

Can you retry the tkprof with "aggregate=NO' one more time ?

Also, if you can, paste the raw trace file.


Hemant K Chitale
Re: How to Change execution plan of Currently Executing Statement? [message #493522 is a reply to message #493500] Tue, 08 February 2011 09:41 Go to previous messageGo to next message
OraKaran
Messages: 183
Registered: March 2008
Location: United Kingdom
Senior Member
Hello Hemant and Michel

Thanks for your replies

Michel
I will try the tweak you have suggested. Though I am confident it will work as expected it will not be real case scenario
I am trying to find out how I can come out of the problematic situation if the query has picked up wrong plan and will continue further for many iterations

Hemant
In fact I tried 'aggregate=no' twice
First it did not gave desired results so I thought it would be TYPO
Again checked tkprof parameters
And though I found I issued proper command jut for the benefit of doubt again tried the command

I have attached the complete trace of the session now (by changing file extension from .trc to .ora)


Quote:

at least in the fourth execution if not the third one as well

BTW how you concluded above? I was trying to see that but could not found

Is it from?
Misses in library cache during parse


Regards,
OraKaran


Re: How to Change execution plan of Currently Executing Statement? [message #493544 is a reply to message #493522] Tue, 08 February 2011 10:20 Go to previous messageGo to next message
hkchital
Messages: 128
Registered: September 2008
Location: Singapore
Senior Member
The tkprof already shows me two different Dynamic Sampling executions, one without an index on the table and one with the index present.

From the raw trace, I see
PARSING IN CURSOR #2 len=46 dep=1 uid=5 oct=3 lid=5 tim=1266767177985754 hv=3933124688 ad='5ec065a0'
SELECT COUNT(1) FROM TAB1 WHERE OBJECT_ID=2331

so that statement is CURSOR #2 and will remain #2 until and unless it is closed.

Then, I see the first execution which read 821 blocks :
EXEC #2:c=0,e=53,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,tim=1266767177985864
FETCH #2:c=27996,e=27768,p=0,cr=821,cu=0,mis=0,r=1,dep=1,og=1,tim=1266767178013660

and the second execution which also read 821 blocks :
EXEC #2:c=0,e=72,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,tim=1266767183884988
FETCH #2:c=6999,e=7353,p=0,cr=821,cu=0,mis=0,r=1,dep=1,og=1,tim=1266767183892363

a third execution which read 2 blocks (also notice the "mis=1" meaning that it had to be re-parsed at this execution)
EXEC #2:c=7999,e=7775,p=1,cr=74,cu=0,mis=1,r=0,dep=1,og=1,tim=1266767189761668
FETCH #2:c=0,e=28,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=1,tim=1266767189761718

and the fourth execution which also read 2 blocks :
EXEC #2:c=0,e=44,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,tim=1266767195622918
FETCH #2:c=0,e=32,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=1,tim=1266767195622971

for a total of 1646 blocks.

However, only one Parse entry was captured. (dep=1 is because it was a "child" of the parent PLSQL block (CURSOR #1) that is at dep=0)
PARSING IN CURSOR #2 len=46 dep=1 uid=5 oct=3 lid=5 tim=1266767177985754 hv=3933124688 ad='5ec065a0'

while Row Source was captured at the end, but appears to be for 2 executions, returning 2 rows (cnt=2 is 2 rows)
STAT #2 id=1 cnt=2 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=4 pr=0 pw=0 time=73 us)'
STAT #2 id=2 cnt=2 pid=1 pos=1 obj=4673976 op='INDEX RANGE SCAN I (cr=4 pr=0 pw=0 time=47 us)'


Instead of running a PLSQL loop, you could manually issue the statement 4 times as an SQL SELECT (creating the index from another session after the first 2 executions).

Also ensure that you EXIT the session before you run a tkprof on the trace file -- else the cursor closure and RowSourceOperations are not captured properly in 10.2. (Of course, alternatively running a completed unrelated SQL like "SELECT 'X' FROM DUAL;" should also force a closure of the cursor).
(11.2 has improved capturing of the STAT# (RowSourceOperations) calls.)

Hemant K Chitale
Re: How to Change execution plan of Currently Executing Statement? [message #493551 is a reply to message #493500] Tue, 08 February 2011 10:45 Go to previous messageGo to next message
OraKaran
Messages: 183
Registered: March 2008
Location: United Kingdom
Senior Member
Hello Hemant

First of all thanks for sharing your observations and conclusion after reading the trace file.

Regarding existing the trace session, Yes. I exited it to close cursors but as you have mentioned, I should have executed dummy 'select x from dual' as a precaution.

I have executed the statements in a loop to simulate a real time scenario.

Once we had some 'Credit Note Preparation' batch process which use to run for 30-40 minutes during daytime.
And may be because of 'bind variable peeking', if it picked the wrong plan, support team had no options but to wait and watch it (and pray) till it finished

Though now I can think we should have checked cursor_sharing setting, using hard coded if possible with histogram, that time it was not possible and it made things worst on few occasions

So as a bottom-line can we say that if a sql is executing in a loop we can't force to change it's execution path externally (from other session)?

Regards,
OraKaran
Re: How to Change execution plan of Currently Executing Statement? [message #493589 is a reply to message #493551] Tue, 08 February 2011 19:30 Go to previous messageGo to next message
hkchital
Messages: 128
Registered: September 2008
Location: Singapore
Senior Member
>So as a bottom-line can we say that if a sql is executing in a loop we can't force to change it's execution path externally (from other session)?
Rubbish. You have proven that you CAN change the execution plan. See the differences between the trace file statistics first 2 and the last 2 execution in your PLSQL loop.

>I have executed the statements in a loop to simulate a real time scenario.
I really don't know if your "real world" program uses a PLSQL loop in this manner. I have seen ETL jobs stupidly use PLSQL loops to insert 1 row at a time but I don't know your real job.

>And may be because of 'bind variable peeking', if it picked the wrong plan, support team had no options but to wait and watch it (and pray) till it finished
Nonsense. They have options that can be executed from other sessions
1. Gather Statistics (with, preferably, no_invalidate=>FALSE)
2. Dummy DDL (e.g. COMMENT ON TABLE ...) to force invalidation of SQLs
3. Adding Indexes


Hemant K Chitale
Re: How to Change execution plan of Currently Executing Statement? [message #493637 is a reply to message #493500] Wed, 09 February 2011 03:21 Go to previous message
OraKaran
Messages: 183
Registered: March 2008
Location: United Kingdom
Senior Member
Hello Hemant

Quote:

>So as a bottom-line can we say that if a sql is executing in a loop we can't force to change it's execution path externally (from other session)?
Rubbish. You have proven that you CAN change the execution plan. See the differences between the trace file statistics first 2 and the last 2 execution in your PLSQL loop.

I apologize. I don't know what made me write that, while I read your earlier reply clearly stating change in plan. I realized my mistake.


Quote:

>I have executed the statements in a loop to simulate a real time scenario.
I really don't know if your "real world" program uses a PLSQL loop in this manner. I have seen ETL jobs stupidly use PLSQL loops to insert 1 row at a time but I don't know your real job.

I agree that sometimes it is mistake of writing pl/sql but other times it is just a requirement.


Quote:

>And may be because of 'bind variable peeking', if it picked the wrong plan, support team had no options but to wait and watch it (and pray) till it finished
Nonsense. They have options that can be executed from other sessions
1. Gather Statistics (with, preferably, no_invalidate=>FALSE)
2. Dummy DDL (e.g. COMMENT ON TABLE ...) to force invalidation of SQLs
3. Adding Indexes


2nd option I never thought of. Thanks for the suggestion. I will try it.
Regarding Option 1, I tried it few days back on Oracle 9i and did not got the desired results. I will try it again
For Option 3, you have proved the change took place exactly when it was supposed to. (for 3rd and 4th execution of the statement)

Once again I am sorry if I have annoyed you with my earlier reply

Thanks and Regards,
OraKaran


Previous Topic: data caching
Next Topic: Application is slow when no of connections goes up
Goto Forum:
  


Current Time: Fri Apr 19 23:16:21 CDT 2024