Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Rajeshwaran.

Asked: September 12, 2015 - 2:41 pm UTC

Last updated: August 01, 2019 - 8:04 am UTC

Version: 11.2.0.4

Viewed 10K+ times! This question is

You Asked

When the child cursor is invalidated, does the next execution of the sql - don't produce the new child cursor? if so what does invalidation mean in v$sql ?

rajesh@ORA11G> drop table emp purge;

Table dropped.

rajesh@ORA11G> create table emp as select * from scott.emp;

Table created.

rajesh@ORA11G> exec dbms_stats.gather_table_stats(user,'emp');

PL/SQL procedure successfully completed.

rajesh@ORA11G> set serveroutput off
rajesh@ORA11G> select count(*) from emp;

  COUNT(*)
----------
        14

1 row selected.

rajesh@ORA11G> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
SQL_ID  g59vz2u4cu404, child number 0
-------------------------------------
select count(*) from emp

Plan hash value: 2083865914

-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |     3 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------


14 rows selected.

rajesh@ORA11G> select child_number,invalidations from v$sql
  2  where sql_id ='g59vz2u4cu404';

CHILD_NUMBER INVALIDATIONS
------------ -------------
           0             0

1 row selected.

rajesh@ORA11G> exec dbms_stats.gather_table_stats(user,'emp',no_invalidate=>false);

PL/SQL procedure successfully completed.

rajesh@ORA11G> select child_number,invalidations from v$sql
  2  where sql_id ='g59vz2u4cu404';

CHILD_NUMBER INVALIDATIONS
------------ -------------
           0             1

1 row selected.

rajesh@ORA11G> select count(*) from emp;

  COUNT(*)
----------
        14

1 row selected.

rajesh@ORA11G> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
SQL_ID  g59vz2u4cu404, child number 0
-------------------------------------
select count(*) from emp

Plan hash value: 2083865914

-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |     3 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------


14 rows selected.

rajesh@ORA11G> select child_number,invalidations from v$sql
  2  where sql_id ='g59vz2u4cu404';

CHILD_NUMBER INVALIDATIONS
------------ -------------
           0             1

1 row selected.

rajesh@ORA11G>

and Connor said...

The documentation for V$SQL says for INVALIDATIONS: "Number of times this child cursor has been invalidated"

So just because a child has been invalidated, doesnt mean it must be discarded entirely, it simply means existing information about the child cannot be used, it must reloaded on next invocation:


SQL> drop table emp purge;

Table dropped.

SQL> create table emp as select * from scott.emp;

Table created.

SQL> exec dbms_stats.gather_table_stats(user,'emp');

PL/SQL procedure successfully completed.

SQL> set serveroutput off
SQL> select count(*) from emp;

  COUNT(*)
----------
        15

SQL> select loads, child_number,invalidations from v$sql where sql_id ='g59vz2u4cu404';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         1            0             0

SQL> exec dbms_stats.gather_table_stats(user,'emp',no_invalidate=>false);

PL/SQL procedure successfully completed.

SQL> select loads, child_number,invalidations from v$sql where sql_id ='g59vz2u4cu404';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         1            0             1

SQL> select count(*) from emp;

  COUNT(*)
----------
        15

SQL> select loads, child_number,invalidations from v$sql where sql_id ='g59vz2u4cu404';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         2            0             1


Even if I totally change the table, the need for another child is not there (assuming no-one else isnt in the middle of using it)

SQL> drop table emp purge;

Table dropped.

SQL> create table emp as select * from scott.emp;

Table created.

SQL> select count(*) from emp;

  COUNT(*)
----------
        15

SQL> select loads, child_number,invalidations from v$sql where sql_id ='g59vz2u4cu404';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         3            0             2

SQL> alter table emp add ( blah int);

Table altered.

SQL> alter table emp drop column empno;

Table altered.

SQL> select count(*) from emp;

  COUNT(*)
----------
        15

SQL> select loads, child_number,invalidations from v$sql where sql_id ='g59vz2u4cu404';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         4            0             3


To expand on this, I re-did this exercise using upper case for the SQL, and then fired up another session and ran:

SQL> declare
  2    rc sys_Refcursor;
  3    x int;
  4  begin
  5    open rc for SELECT COUNT(*) FROM EMP;
  6    fetch rc into x;
  7    dbms_lock.sleep(30);
  8  close rc;
  9  end;
 10  /

PL/SQL procedure successfully completed.


thus the first child is *in use* for at least 30 seconds. I than added a column to EMP, whilst that was running

SQL> alter table emp add ( blah3 int);

Table altered.

SQL> SELECT COUNT(*) FROM EMP;

  COUNT(*)
----------
        15

SQL> select loads, child_number,invalidations from v$sql where sql_id ='79bg9cb9a77v2';

     LOADS CHILD_NUMBER INVALIDATIONS
---------- ------------ -------------
         2            0             1
         1            1             1


and notice another child IS created, because the first one cannot be touched (its in use)

Hope this helps.

Rating

  (2 ratings)

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

Comments

Fine Grained cursor in-validations

Rajeshwaran Jeyabal, July 29, 2019 - 12:49 pm UTC

Team,

was reading about Fine Grainded cursor invalidation from Optimizer blog https://blogs.oracle.com/optimizer/fine-grained-cursor-invalidation

and from documentation at
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/tgsql/improving-rwp-cursor-sharing.html#GUID-0BCC0D7A-F1E9-4173-B123-F175BC236588

Could you help with a test case to show when does DDL_NO_INVALIDATE in V$SQL will be set to "Y"? tried few test cases but that doesn't workout.

Connor McDonald
July 30, 2019 - 3:31 am UTC

SQL> create table t as select * from all_objects;

Table created.

SQL>
SQL> set feedback on sql_id
SQL>
SQL> select count(*) from t;

  COUNT(*)
----------
     76870

1 row selected.

SQL_ID: cyzznbykb509s
SQL>
SQL> select * from v$sql where sql_id = 'cyzznbykb509s'
  2  @pr
SQL_ID: b3s1x9zqrvzvc
==============================
SQL_TEXT                      : select count(*) from t
SQL_FULLTEXT                  : select count(*) from t
SQL_ID                        : cyzznbykb509s
SHARABLE_MEM                  : 19383
PERSISTENT_MEM                : 46840
RUNTIME_MEM                   : 45440
SORTS                         : 0
LOADED_VERSIONS               : 1
OPEN_VERSIONS                 : 0
USERS_OPENING                 : 0
FETCHES                       : 1
EXECUTIONS                    : 1
PX_SERVERS_EXECUTIONS         : 0
END_OF_FETCH_COUNT            : 1
USERS_EXECUTING               : 0
LOADS                         : 1
FIRST_LOAD_TIME               : 2019-07-30/11:30:17
INVALIDATIONS                 : 0
PARSE_CALLS                   : 1
DISK_READS                    : 1498
DIRECT_WRITES                 : 0
DIRECT_READS                  : 0
BUFFER_GETS                   : 1503
APPLICATION_WAIT_TIME         : 0
CONCURRENCY_WAIT_TIME         : 0
CLUSTER_WAIT_TIME             : 0
USER_IO_WAIT_TIME             : 28767
PLSQL_EXEC_TIME               : 0
JAVA_EXEC_TIME                : 0
ROWS_PROCESSED                : 1
COMMAND_TYPE                  : 3
OPTIMIZER_MODE                : ALL_ROWS
OPTIMIZER_COST                : 417
OPTIMIZER_ENV                 :
E289FB8990CF12014F021000AEF5C3E2CFFA331056414555519521105545551545545558591555449665851D5511058555555155515122555415A0EA0C55514542
65455454449081566E001696C6A355451501025415504416FD557151551555551001550A16214545D1C35444A1011015595510250153355555555551E95F141185
5B0501655D56456144551525245005F9A4160190505165551695508416E4B344400103008000000000040000400000000800800002F401000000530600CA430140
400000000E3E00010000E5A1000080290300E4B344401919998000998C800C008000C08080824241810205800000007D000000998282820219FA0000001930E080
00800000C0FF3F000003830C1000100000FA000000C40900000008008082C700320000020040000000C40900C00041A002A0252600FA0000C012D9FF3F00C0FF3F
00000004000005A86100001910881300C0810032F208FE3F00C0FF3F00800001900205940C
OPTIMIZER_ENV_HASH_VALUE      : 1989187227
PARSING_USER_ID               : 104
PARSING_SCHEMA_ID             : 104
PARSING_SCHEMA_NAME           : MCDONAC
KEPT_VERSIONS                 : 0
ADDRESS                       : 00007FF96D7821B8
TYPE_CHK_HEAP                 : 00
HASH_VALUE                    : 2763161912
OLD_HASH_VALUE                : 2816538551
PLAN_HASH_VALUE               : 2966233522
FULL_PLAN_HASH_VALUE          : 1071362934
CHILD_NUMBER                  : 0
SERVICE                       : pdb1
SERVICE_HASH                  : 0
MODULE                        : SQL*Plus
MODULE_HASH                   : -625018272
ACTION                        :
ACTION_HASH                   : 0
SERIALIZABLE_ABORTS           : 0
OUTLINE_CATEGORY              :
CPU_TIME                      : 31250
ELAPSED_TIME                  : 54873
OUTLINE_SID                   :
CHILD_ADDRESS                 : 00007FF96D7751F0
SQLTYPE                       : 6
REMOTE                        : N
OBJECT_STATUS                 : VALID
LITERAL_HASH_VALUE            : 0
LAST_LOAD_TIME                : 2019-07-30/11:30:17
IS_OBSOLETE                   : N
IS_BIND_SENSITIVE             : N
IS_BIND_AWARE                 : N
IS_SHAREABLE                  : Y
CHILD_LATCH                   : 0
SQL_PROFILE                   :
SQL_PATCH                     :
SQL_PLAN_BASELINE             :
PROGRAM_ID                    : 0
PROGRAM_LINE#                 : 0
EXACT_MATCHING_SIGNATURE      : 8733064096160086462
FORCE_MATCHING_SIGNATURE      : 8733064096160086462
LAST_ACTIVE_TIME              : 30-JUL-19
BIND_DATA                     :
TYPECHECK_MEM                 : 0
IO_CELL_OFFLOAD_ELIGIBLE_BYTES: 0
IO_INTERCONNECT_BYTES         : 12271616
PHYSICAL_READ_REQUESTS        : 27
PHYSICAL_READ_BYTES           : 12271616
PHYSICAL_WRITE_REQUESTS       : 0
PHYSICAL_WRITE_BYTES          : 0
OPTIMIZED_PHY_READ_REQUESTS   : 0
LOCKED_TOTAL                  : 1
PINNED_TOTAL                  : 2
IO_CELL_UNCOMPRESSED_BYTES    : 0
IO_CELL_OFFLOAD_RETURNED_BYTES: 0
CON_ID                        : 3
IS_REOPTIMIZABLE              : N
IS_RESOLVED_ADAPTIVE_PLAN     :
IM_SCANS                      : 0
IM_SCAN_BYTES_UNCOMPRESSED    : 0
IM_SCAN_BYTES_INMEMORY        : 0
DDL_NO_INVALIDATE             : N
IS_ROLLING_INVALID            : N
IS_ROLLING_REFRESH_INVALID    : N
RESULT_CACHE                  : N

PL/SQL procedure successfully completed.

SQL> alter table t read only;

Table altered.

SQL> select * from v$sql where sql_id = 'cyzznbykb509s'
  2  @pr
==============================
SQL_TEXT                      : select count(*) from t
SQL_FULLTEXT                  : select count(*) from t
SQL_ID                        : cyzznbykb509s
SHARABLE_MEM                  : 19383
PERSISTENT_MEM                : 46840
RUNTIME_MEM                   : 45440
SORTS                         : 0
LOADED_VERSIONS               : 1
OPEN_VERSIONS                 : 0
USERS_OPENING                 : 0
FETCHES                       : 1
EXECUTIONS                    : 1
PX_SERVERS_EXECUTIONS         : 0
END_OF_FETCH_COUNT            : 1
USERS_EXECUTING               : 0
LOADS                         : 1
FIRST_LOAD_TIME               : 2019-07-30/11:30:17
INVALIDATIONS                 : 0
PARSE_CALLS                   : 1
DISK_READS                    : 1498
DIRECT_WRITES                 : 0
DIRECT_READS                  : 0
BUFFER_GETS                   : 1503
APPLICATION_WAIT_TIME         : 0
CONCURRENCY_WAIT_TIME         : 0
CLUSTER_WAIT_TIME             : 0
USER_IO_WAIT_TIME             : 28767
PLSQL_EXEC_TIME               : 0
JAVA_EXEC_TIME                : 0
ROWS_PROCESSED                : 1
COMMAND_TYPE                  : 3
OPTIMIZER_MODE                : ALL_ROWS
OPTIMIZER_COST                : 417
OPTIMIZER_ENV                 :
E289FB8990CF12014F021000AEF5C3E2CFFA331056414555519521105545551545545558591555449665851D5511058555555155515122555415A0EA0C55514542
65455454449081566E001696C6A355451501025415504416FD557151551555551001550A16214545D1C35444A1011015595510250153355555555551E95F141185
5B0501655D56456144551525245005F9A4160190505165551695508416E4B344400103008000000000040000400000000800800002F401000000530600CA430140
400000000E3E00010000E5A1000080290300E4B344401919998000998C800C008000C08080824241810205800000007D000000998282820219FA0000001930E080
00800000C0FF3F000003830C1000100000FA000000C40900000008008082C700320000020040000000C40900C00041A002A0252600FA0000C012D9FF3F00C0FF3F
00000004000005A86100001910881300C0810032F208FE3F00C0FF3F00800001900205940C
OPTIMIZER_ENV_HASH_VALUE      : 1989187227
PARSING_USER_ID               : 104
PARSING_SCHEMA_ID             : 104
PARSING_SCHEMA_NAME           : MCDONAC
KEPT_VERSIONS                 : 0
ADDRESS                       : 00007FF96D7821B8
TYPE_CHK_HEAP                 : 00
HASH_VALUE                    : 2763161912
OLD_HASH_VALUE                : 2816538551
PLAN_HASH_VALUE               : 2966233522
FULL_PLAN_HASH_VALUE          : 1071362934
CHILD_NUMBER                  : 0
SERVICE                       : pdb1
SERVICE_HASH                  : 0
MODULE                        : SQL*Plus
MODULE_HASH                   : -625018272
ACTION                        :
ACTION_HASH                   : 0
SERIALIZABLE_ABORTS           : 0
OUTLINE_CATEGORY              :
CPU_TIME                      : 31250
ELAPSED_TIME                  : 54873
OUTLINE_SID                   :
CHILD_ADDRESS                 : 00007FF96D7751F0
SQLTYPE                       : 6
REMOTE                        : N
OBJECT_STATUS                 : VALID
LITERAL_HASH_VALUE            : 0
LAST_LOAD_TIME                : 2019-07-30/11:30:17
IS_OBSOLETE                   : N
IS_BIND_SENSITIVE             : N
IS_BIND_AWARE                 : N
IS_SHAREABLE                  : Y
CHILD_LATCH                   : 0
SQL_PROFILE                   :
SQL_PATCH                     :
SQL_PLAN_BASELINE             :
PROGRAM_ID                    : 0
PROGRAM_LINE#                 : 0
EXACT_MATCHING_SIGNATURE      : 8733064096160086462
FORCE_MATCHING_SIGNATURE      : 8733064096160086462
LAST_ACTIVE_TIME              : 30-JUL-19
BIND_DATA                     :
TYPECHECK_MEM                 : 0
IO_CELL_OFFLOAD_ELIGIBLE_BYTES: 0
IO_INTERCONNECT_BYTES         : 12271616
PHYSICAL_READ_REQUESTS        : 27
PHYSICAL_READ_BYTES           : 12271616
PHYSICAL_WRITE_REQUESTS       : 0
PHYSICAL_WRITE_BYTES          : 0
OPTIMIZED_PHY_READ_REQUESTS   : 0
LOCKED_TOTAL                  : 1
PINNED_TOTAL                  : 2
IO_CELL_UNCOMPRESSED_BYTES    : 0
IO_CELL_OFFLOAD_RETURNED_BYTES: 0
CON_ID                        : 3
IS_REOPTIMIZABLE              : N
IS_RESOLVED_ADAPTIVE_PLAN     :
IM_SCANS                      : 0
IM_SCAN_BYTES_UNCOMPRESSED    : 0
IM_SCAN_BYTES_INMEMORY        : 0
DDL_NO_INVALIDATE             : Y
IS_ROLLING_INVALID            : N
IS_ROLLING_REFRESH_INVALID    : N
RESULT_CACHE                  : N

PL/SQL procedure successfully completed.

SQL>

Fine Grained cursor in-validations

Rajeshwaran Jeyabal, July 30, 2019 - 6:15 am UTC

what version was used for the above demo?

Tried this in 12.2 (hence provided the above documentation reference to 12.2) but doesn't work.

demo@PDB1> create table t as select * from all_objects;

Table created.

demo@PDB1> set serveroutput off
demo@PDB1> select max(created) from t where object_id between 50 and 60;

MAX(CREATED
-----------


demo@PDB1> select * from table( dbms_xplan.display_cursor );

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
SQL_ID  422mtnpt1cuww, child number 0
-------------------------------------
select max(created) from t where object_id between 50 and 60

Plan hash value: 2966233522

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |   337 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |    13 |            |          |
|*  2 |   TABLE ACCESS FULL| T    |     1 |    13 |   337   (1)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(("OBJECT_ID"<=60 AND "OBJECT_ID">=50))


19 rows selected.

demo@PDB1> select DDL_NO_INVALIDATE,IS_ROLLING_INVALID,IS_ROLLING_REFRESH_INVALID
  2  from v$sql
  3  where sql_id ='422mtnpt1cuww';

D I I
- - -
N N N

demo@PDB1> alter table t read only;

Table altered.

demo@PDB1> select DDL_NO_INVALIDATE,IS_ROLLING_INVALID,IS_ROLLING_REFRESH_INVALID
  2  from v$sql
  3  where sql_id ='422mtnpt1cuww';

D I I
- - -
N N N

demo@PDB1>


So Kindly help us with the test case for 12.2 database?

Also as mentioned in the optimizer blog ( https://blogs.oracle.com/optimizer/fine-grained-cursor-invalidation )

<quote>
There are four actions that we can take for a cursor:

Cursor remains valid -- this is used when we know that the cursor is safe to execute and that the cursor's plan is still optimal. 
   For example, modifying a table partition to read only.
   
Cursor is marked for rolling invalidation -- this is used when we know that the cursor is safe to execute but its plan may be sub-optimal. 
  For example, if we create a visible index, then the cursor is safe to execute 
  but we want to recompile it sometime in the future so the new index can be considered for the plan.
  
Cursor is marked for rolling invalidation with metadata refresh -- this is used when the cursor is safe to execute after refreshing some of its metadata at runtime. 
 For example, if we rebuild an index that is used by the cursor, 
 then the cursor can be executed if we refresh the metadata for the index so the cursor uses the new index segment.
 
Cursor is invalidated -- this is used if the cursor is no longer safe to execute. 
 For example, if we drop an index that is used by the cursor, 
 we must invalidate the cursor so it is recompiled to get a new plan that does not use the index.
 
Note that actions 1, 2, and 3 correspond to DDL_NO_INVALIDATE, IS_ROLLING_INVALID, and IS_ROLLING_REFRESH_INVALID columns in V$SQL. 
Action 4 is simply the existing invalidation action that was used prior to the fine-grained invalidation feature.
</quote>


Tried even with partitioned tables, it doesn't works.

Here is the test case for partitioned tables.
demo@PDB1> create table t
  2  partition by hash( object_id )
  3  ( partition p1,
  4    partition p2 )
  5  as
  6  select * from all_objects ;

Table created.

demo@PDB1>
demo@PDB1> set serveroutput off
demo@PDB1> select max(created) from t where object_id between 50 and 60;

MAX(CREATED
-----------


demo@PDB1> select * from table( dbms_xplan.display_cursor );

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
SQL_ID  422mtnpt1cuww, child number 0
-------------------------------------
select max(created) from t where object_id between 50 and 60

Plan hash value: 2174430098

--------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |       |       |   339 (100)|          |       |       |
|   1 |  SORT AGGREGATE     |      |     1 |    13 |            |          |       |       |
|   2 |   PARTITION HASH ALL|      |     1 |    13 |   339   (1)| 00:00:01 |     1 |     2 |
|*  3 |    TABLE ACCESS FULL| T    |     1 |    13 |   339   (1)| 00:00:01 |     1 |     2 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(("OBJECT_ID"<=60 AND "OBJECT_ID">=50))


20 rows selected.

demo@PDB1> select DDL_NO_INVALIDATE,IS_ROLLING_INVALID,IS_ROLLING_REFRESH_INVALID
  2  from v$sql
  3  where sql_id ='422mtnpt1cuww';

D I I
- - -
N N N

demo@PDB1> alter table t modify partition p1 read only;

Table altered.

demo@PDB1> select DDL_NO_INVALIDATE,IS_ROLLING_INVALID,IS_ROLLING_REFRESH_INVALID
  2  from v$sql
  3  where sql_id ='422mtnpt1cuww';

D I I
- - -
N N N

demo@PDB1>

Connor McDonald
August 01, 2019 - 8:04 am UTC

From the same blog post you referred to:

"Note that we have not documented the multitude of factors that affect where this feature will or will not kick in. This is where the differences between Oracle Database 12c and Oracle Database 18c are, so the changes between these two releases will not be obvious from the documentation. "

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library