Subscribe to Posts by Email

Subscriber Count

    701

Disclaimer

All information is offered in good faith and in the hope that it may be of use for educational purpose and for Database community purpose, but is not guaranteed to be correct, up to date or suitable for any particular purpose. db.geeksinsight.com accepts no liability in respect of this information or its use. This site is independent of and does not represent Oracle Corporation in any way. Oracle does not officially sponsor, approve, or endorse this site or its content and if notify any such I am happy to remove. Product and company names mentioned in this website may be the trademarks of their respective owners and published here for informational purpose only. This is my personal blog. The views expressed on these pages are mine and learnt from other blogs and bloggers and to enhance and support the DBA community and this web blog does not represent the thoughts, intentions, plans or strategies of my current employer nor the Oracle and its affiliates or any other companies. And this website does not offer or take profit for providing these content and this is purely non-profit and for educational purpose only. If you see any issues with Content and copy write issues, I am happy to remove if you notify me. Contact Geek DBA Team, via geeksinsights@gmail.com

Pages

Quick Question: How to invalidate the cursor after statistics gathering

A long running job and you have identified that statistics of a table is causing sub optimal plan and you have gathered the statistics and asked teams to rerun the job. But still picking old plan or the statistics which should not, the reasons are and how to invalidate the cursor in library cache (SQL AREA)

1. when no_invalidate = false (default as of 9i)
Change in statistics makes all dependent cursors invalidated immediately.

2. when no_invalidate = true
Change in statistics makes no invalidation. New execution plan is generated only after the cursor is flushed out and reloaded.

3. when no_invalidate = dbms_stats.auto_invalidate (default as of 10g/11g)
The most interesting case. Change in statistics makes all dependent cursors invalidated after some specific period of time. This time is determined by the hidden parameter "_optimizer_invalidation_period". The default value of this parameter is 18000(s) == 5 hour.

The weird thing is that this does not make the dependent cursor "really invalidated". Instead, new child cursor is generated when the cursor is accessed after time has expired. v$sql_shared_cursor.roll_invalid_mismatch is 'Y' on those child cursors, Oracle does a hard parse when ROLL_INVALID_MISMATCH flag/bit is set. Like this.

According to Point 3, you have to wait 5 Hours to make your cursor invalidated,

So how to invalidate the cursor immediately,

1) SQL> alter system set "_optimizer_invalidation_period" = 60 scope=memory; (default is 18000 or 5 hours)
System altered.
Note: this is at system level so may give weird results

2) Quicker option is to comment any of the one of the column in the referenced table of query and comment is DDL, when DDL fires the statement will be invalidated, finally revert back the comment to null.

SQL> comment on table x 'test';
once done, revert
SQL> comment on table x null;

3) Append any hint so that its look like different sql statement (if you can change the query)
SQL> Select /*+ test */

Hope this helps.

Comments are closed.