What exactly is PLAN_TABLE in Oracle Database?

Every user session on Oracle database will be able to access default table PLAN_TABLE to collect execution plan of a query from EXPLAIN PLAN command. But, how is this table available to all the users in the database and gets empty once you disconnect? Is this table available and created for every user logging into the database or is it a global table and available publicly to access? I am sure that you must have got little excited with these questions and we are going to get answers for many such questions in this blog with the help of a step-by-step analytic approach. In our earlier articles “EXPLAIN PLAN for multiple SQL statements”, “Ways of generating EXECUTION PLAN in Oracle Database” we have clearly understood the usage of PLAN_TABLE to generate execution plan for a query. In this blog, we are going to see what exactly is this PLAN_TABLE and all the concepts around its existence.

Basics:

[oracle@PT-DB ~]$ cd $ORACLE_HOME/rdbms/admin/utlxplan.sql

create table PLAN_TABLE (

statement_id       varchar2(30),

plan_id            number,

timestamp          date,

remarks            varchar2(4000),

….);

  • It has got just one DDL to create PLAN_TABLE in the schema you are connected to when running this SQL file. So it doesn’t actually give us good details of why is this now available in 11gR2(Which I am using). Let us start our analysis with our case study now.

How is #PLAN_TABLE accessible by all sessions in #Oracle #database? Click To Tweet

Case study:

SQL> col OBJECT_NAME for a20

SQL> select object_name,OBJECT_TYPE from dba_objects where object_name=’PLAN_TABLE’;

OBJECT_NAME  OBJECT_TYPE

—————- ————————————————

PLAN_TABLE   SYNONYM

SQL>select dbms_metadata.get_ddl(‘SYNONYM’,’PLAN_TABLE’,’PUBLIC’) from dual;

CREATE OR REPLACE PUBLIC SYNONYM “PLAN_TABLE” FOR “SYS”.”PLAN_TABLE$”

  • Now it is clear that PLAN_TABLE is a PUBLIC synonym of SYS.PLAN_TABLE$ and so it is accessible by all the users.
  • But the question still alive that how this table contents are erased every time session gets disconnected. Let us go further into the analysis.
  • At this moment, I could recollect the concepts of GLOBAL TEMPORAY TABLES (GTT) which have got the feature of cleaning up the data in the table after the session disconnects. So let us check if SYS.PLAN_TABLE$ is a GTT.

SQL> select table_name,TEMPORARY from dba_tables where table_name=’PLAN_TABLE$’;

TABLE_NAME   T

—————————— ———-

PLAN_TABLE$  Y

  • There it is!!! We got to know that PLAN_TABLE$ is a GLOBAL TEMPORARY TABLE and PLAN_TABLE is a PUBLIC SYNONYM which is why it is available for all the users to access and data gets erased as soon as session disconnects.
  • Having understand the type of the object, let us try to find where exactly the data is temporarily stored until the user session disconnects. To achieve this let me check with the following query.

SQL> select table_name,TEMPORARY,tablespace_name from dba_tables where table_name=’PLAN_TABLE$’;

TABLE_NAME   T TABLESPACE_NAME

—————————— ————– —————–

PLAN_TABLE$  Y

  • Oops!!! There is not tablespace_name for this object at all. Does it mean that data is not stored in the segments at all? No, GTT data is always stored in the data file segments. But how do we recognize which tablespace segment? From the core concepts of Global Temporary Tables from Oracle document, the default segments used by global temporary tables are from the default temporary tablespace of the user session.
  • Let us check if the PLAN_TABLE has some data and parallel check temporary tablespace segment usage.

SQL> select count(*) from plan_table;

COUNT(*)

———-

0

SQL> select USER,BLOCKS from v$tempseg_usage;

no rows selected

  • I am going to run EXPLAIN PLAN of a query and re-check the same as above.

SQL> explain plan for select * from v$session;

Explained.

SQL> select count(*) from plan_table;

COUNT(*)

———-

6

SQL> select USER,BLOCKS from v$tempseg_usage;

USER             BLOCKS

———————- ———————————–

SYS              128

SYS              128

SYS              128

  • Excited!!! This proves that data of PLAN_TABLE is stored in temporary tablespace of the database.

Interesting facts and findings about #PLAN_TABLE in #Oracle #Database Click To Tweet

  • As we see single table SYS.PLAN_TABLE$ is used by all the concurrent sessions in the database, let us check if data in this table is private to each session.

SYS connection:

SQL> select count(*) from sys.plan_table$;

COUNT(*)

———-

0

Session 1:

SQL> explain plan for select * from v$session;

Explained.

SQL> select count(*) from sys.plan_table$;

COUNT(*)

———-

6

SYS connection:

SQL> select count(*) from sys.plan_table$;

COUNT(*)

———-

0

  • This is how GTT tables work, data from the table is bundled to the session which writes the data.
  • Unfortunately, there is no method to check which session occupying what space of temporary segments for any Global Temporary Tables.
  • Does this table have any indexes created by default? Let us check that if so.

SQL>  select index_name,index_type from dba_indexes where TABLE_NAME=’PLAN_TABLE$’;

INDEX_NAME            INDEX_TYPE

————– ———————————————————————————-

SYS_IL0000005124C00027$$  LOB

  • Which means that this is the index created for LOB columns in the table by default by the database. So PLAN_TABLE$ have a LOB column in it. Apart from that there are no indexes created on this table.

Further interesting questions:

  • Will optimizer write an execution plan when you query PLAN_TABLE and if so what access paths it will use?
  • Can we gather stats on any Global Temporary Table and how can we verify them?

I will leave these questions to answer yourself by continuing exciting analysis of this case study 🙂

Conclusion:

I love to see your comments!

Feel free to give additional information in the comments, that I can validate and include in blog posts or update this as well.

Related Posts

About The Author

9 Comments

  1. sridharkumar.sahu@yahoo.com'
    Sridhar kumar sahu
    April 14, 2016
    • Pawan Kumar Yaddanapudi
      April 15, 2016
  2. sonu6252@gmail.com'
    Rajat Samanta
    April 30, 2016
    • Pawan Kumar Yaddanapudi
      April 30, 2016
  3. miteshturakhiya1605@gmail.com'
    Mitesh Turakhiya
    June 23, 2016
    • Pawan Kumar Yaddanapudi
      June 23, 2016
  4. ronald.sunny@gmail.com'
    Ronald
    September 20, 2016
    • Pawan Kumar Yaddanapudi
      October 25, 2016
  5. kkarthick16591@gmail.com'
    Karthick
    April 26, 2017

Add Comment