Tuesday, February 10, 2009

Is that database affected with "Bind Peeking"!!!

Complaint:
The procedure that was written couple of years ago was running fine and smooth until we upgraded to 10g (Rel#1).
Even, in 10g it was fine for the first few weeks and then slowly started seeing lot of slowness in the system.
The stats found out this particular sql as the main culprit.
Amazingly 3GB TEMP tablespace in 8i is not enough in 10G. The TEMP tablespace grows even upto 24G (well thank god thats the max limit they set) and then fails.
Whats going on...
Din't think about this so called feature "bind peeking" from 9i but started looking into the culprit sql.
The SQL is not that complex. It has group by and one sub query. Thats all. And yeah, this SQL is the cursor though. Since its a cursor, there is a variable assignment for a where clause to filter out the records and that variable is of "date" type and the column compares this variable also is of "date" type in the table. So, everything is good there and I don't have to go for converting my variable to to_date etc.,
Well, so, why is that this particular SQL taking too much of TEMP tablespace!!!
Ran the query alone by passing the actual value instead of the variable in where clause to see how many records I get. Interestingly I get only couple of hundred rows.
That made me to think of the variable being binded in the cursor at the runtime.
So, this time my test was little different. Made a pl/sql block with the cursor and passed the variable value at run time (basically pulled out the portion of the code from the procedure) and the query hangs while being busy in increasing the temp space.
Removed the variable in the where clause and changed to get the value directly from the table instead of assigning that at the run time. Boom... query comes back in seconds...
So, my guess was right. Its the bind variable which was causing the issue and some how oracle keep increasing the temp tablespace.
Solution:
Basically the main issue here was to do with the so called feature "bind peeking". In this example while oracle was trying to get the bind variable value from the list when it was issued at the very first time after the database was started and never looked into the current value set. So, the data set returning was huge...
Well, time to disable this feature "bind peeking".
Here is the way to disable it:
There is an Oracle Hidden parameter which allows to disable it and that parameter is
"_optim_peek_user_binds" by default it is enabled.
alter system set "_optim_peek_user_binds" = false scope=both; --> system wide immediate effect and also modifies the spfile
alter session set "_optim_peek_user_binds" = false --> only for the session so that you can test your code.

Good luck with "bind peeking".

No comments:

Post a Comment