Query regarding Explain Plan

Hi,
I have a query regarding explain plan. While we gather the statistics then optimize choose the best possible plan out of the explain plans available. If we do not gather statistics on a table for a long time then which plan it choose:
If it will continue to use the same plan as it use in the starting when statistics were gathered or will change the plan as soon as dml activities performed and statistics getting old.
Thanks
GK

Hi,
Aman.... wrote:
Gulshan wrote:
Hi,
I have a query regarding explain plan. While we gather the statistics then optimize choose the best possible plan out of the explain plans available. If we do not gather statistics on a table for a long time then which plan it choose:The same plan which it has chosen in the starting with the previous statistics. The plan won't change automatically as long as you won't refresh the statistics. This is wrong even for Oracle 9i. Here are couple of examples when a plan might change with the same optimizer statistics:
* when you have a histogram on a column and are not a bright person to use bind variables, you might get a completely different execution plan because of a different incoming value. All that is needed to fall into this habit - a soft parse, which might be due to different reasons, for instance, due to session parameter modification (which also might change a plan even without a histogram)
* Starting with 10g, CBO makes adjustments to cardinality estimates for out of range values appeared in predicates

Similar Messages

  • Query Regarding Explain Plan on Query

    Hello,
    I have one big query which shows report of 50000 daily records from @ 20,00,000 records.
    I have two databases UAT and PROD.when i do Explain Plan on the query is these different database i get the different plan where everything is same in both database.
    In UAT it is doing Index scan where as in PROD it is doing Full TableScan. Below are the results.
    In production it is not using any of the indexes present but in UAT it is.What could be the reasong behind this?

    Sure.
    UAT Explain Plan (Please copy in Textpad for better View)
    SELECT STATEMENT, GOAL = HINT: ALL_ROWS     Cost=371     Cardinality=238     Optimizer=HINT: ALL_ROWS     Bytes=134470
    VIEW     Object owner=SWNET1          Cost=371     Cardinality=238          Bytes=134470
    COUNT STOPKEY                              
    VIEW     Object owner=SWNET1          Cost=371     Cardinality=238          Bytes=131376
    SORT ORDER BY STOPKEY          Cost=371     Cardinality=238          Bytes=54026
    FILTER                              
    HASH JOIN RIGHT ANTI          Cost=370     Cardinality=238          Bytes=54026
    INLIST ITERATOR                              
    TABLE ACCESS BY INDEX ROWID     Object owner=SWNET1     Object name=IS_TB_END_POINT     Cost=1     Cardinality=1     Optimizer=ANALYZED     Bytes=31
    INDEX RANGE SCAN          Object owner=SWNET1     Object name=IS_UK_EP_NAME     Cost=1     Cardinality=1     Optimizer=ANALYZED     
    TABLE ACCESS BY INDEX ROWID     Object owner=SWNET1     Object name=IS_TB_TRANSACTION     Cost=368     Cardinality=253     Optimizer=ANALYZED     Bytes=49588
    INDEX FULL SCAN          Object owner=SWNET1     Object name=IS_IX_T_DESTINATION_EP     Cost=18     Cardinality=13909     Optimizer=ANALYZED
    PRODUCTION Explain Plan
    SELECT STATEMENT, GOAL = HINT: ALL_ROWS               Cost=65702     Cardinality=1000     Optimizer=HINT: ALL_ROWS     Bytes=565000
    VIEW     Object owner=SWNET1          Cost=65702     Cardinality=1000          Bytes=565000
    COUNT STOPKEY                              
    VIEW     Object owner=SWNET1          Cost=65702     Cardinality=38739          Bytes=21383928
    SORT ORDER BY STOPKEY          Cost=65702     Cardinality=38739          Bytes=9646011
    FILTER                              
    HASH JOIN RIGHT ANTI          Cost=63616     Cardinality=38739          Bytes=9646011
    INLIST ITERATOR                              
    TABLE ACCESS BY INDEX ROWID     Object owner=SWNET1     Object name=IS_TB_END_POINT     Cost=1     Cardinality=2     Optimizer=ANALYZED     Bytes=64
    INDEX UNIQUE SCAN          Object owner=SWNET1     Object name=IS_UK_EP_NAME     Cost=1     Cardinality=2     Optimizer=ANALYZED     
    TABLE ACCESS FULL          Object owner=SWNET1     Object name=IS_TB_TRANSACTION     Cost=63614     Cardinality=44697     Optimizer=ANALYZED     Bytes=9699249
    Index Query (Same on both places)
    create index IS_IX_T_DESTINATION_EP on IS_TB_TRANSACTION (T_DESTINATION_EP)
    tablespace IS_XML_IND
    pctfree 10
    initrans 2
    maxtrans 255
    storage
    initial 128M
    next 128K
    minextents 1
    maxextents unlimited
    pctincrease 0
    );

  • Query of explain plan

    1)explain plan
    set statement_id='anu_a_1'
    for select i.name from a i,b j
    where i.id=j.id1
    order by i.id
    when i am trying to select rows from plan table
    what is the purpose of id,parent_id column
    what is the meaning of these output which is associated with 1st query.
    OPERATION          OPTIONS          
    SORT               ORDER BY     
    when i am trying to run 2nd query
    2)explain plan
    set statement_id='anu_a_1'
    for select * from a
    where id=10
    order by id
    OPERATION          OPTIONS          
    SORT               ORDER BY
    these are not come
    why i am using here same order by clause.

    Study the documentation.
    http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96533/opt_ops.htm#1005137
    SORT ORDER BY
    SORT ORDER BY is required when the statement specifies an ORDER BY that cannot be satisfied by one of the indexes
    Rgds.

  • General queries regarding explain plan and query

    Hello Oracle buddies,
    I have few badly formed queries with plenty of nested loops, merge join cartesian , plenty of sorting and in the query so many sub queries and all.. The cost of the queries are high like anything.
    some even has 130Crore of cost .
    When I got the chance to look into those quries I test them in Non Prod systems and which almost have 90-95% similar data as it was refresh by PROD few weeks back.
    I found few queries are having the same explain plan but cost is less like anything. for example 5000 or 6000.
    When I check for the possibilities of wrong statistics I found they just collect with default setting...
    In Non prod I saw only the auto stat job is ran and most of the tables are having the stats which are of last analyzed on the day of refresh.
    Now what could be so differentiating factor that drives a queries' cost lesser than Prod systems, when the data is almost same. Also if prod ssystem is gather by only gather_schema_stat('SCHEMA_NAME') then it should carry the same stat in non prod while refreshing. I know ppl do not gather stat on test only auto job is running ...
    I need to have clear prove before I can have a clear understanding..
    Please help me to know what factors could be differentiating?
    -Regards,
    J_DBA_Sourav

    j_DBA_sourav wrote:
    Hello Jonathan,
    Thanks for the reply. The team refreshed it, by expdp/impdp method where by default statistics are included. In that case?
    Is this problem probable to happen due to statistics only or anything else is also responsible. Even the explain plan is same.
    Please through some light on it.
    Auto job is on as I stated earlier but in test systems most of the tables are showing refreshed date as last_analyzed
    -Regards
    JDS
    Anything that puts the stats out of sync with each other may be sufficient to cause problems. Any queries that depend on sysdate may cause a problem.
    As a simple check:  select table_name, last_analyzed from user_tables on the two systems, with some order by clause (e.g. table_name), and see how many tables were analysed at different times - anything on either system after the exp/imp could be part of your problem.
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    Now on Twitter: @jloracle

  • Any room for improvement for this query? Explain Plan attached.

    Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??
    select sum(CONF
                 when (cd.actl_qty - cd.total_alloc_qty - lsd.Q < 0) then
                  0
                 else
                  cd.actl_qty - cd.total_alloc_qty - lsd.Q
               end)
      from (select sum(reqd_qty) as Q, ITEM_ID as ITEM
              from SHIP_DTL SD
             where exists (select 1
                      from CONF_dtl
                     where CONF_nbr = '1'
                       and ITEM_id = SD.ITEM_id)
             group by ITEM_id) lsd,
           CONF_dtl cd
    where lsd.ITEM = cd.ITEM_id
       and cd.CONF_nbr = '1'Total number of rows in the tables involved
    select count(*) from CONF_DTL;
      COUNT(*)
       1785889
    select count(*) from shp_dtl;
      COUNT(*)
        286675
      Explain Plan
    PLAN_TABLE_OUTPUT
    Plan hash value: 2325658044
    | Id  | Operation                           | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                    |                    |     1 |    39 |     4  (25)| 00:00:01 |
    |   1 |  SORT AGGREGATE                     |                    |     1 |    39 |            |          |
    |   2 |   VIEW                              |                    |     1 |    39 |     4  (25)| 00:00:01 |
    |   3 |    HASH GROUP BY                    |                    |     1 |   117 |     4  (25)| 00:00:01 |
    |   4 |     TABLE ACCESS BY INDEX ROWID     | SHIP_DTL           |     1 |    15 |     1   (0)| 00:00:01
    |   5 |      NESTED LOOPS                   |                    |     1 |   117 |     3   (0)| 00:00:01 |
    |   6 |       MERGE JOIN CARTESIAN          |                    |     1 |   102 |     2   (0)| 00:00:01 |
    |   7 |        TABLE ACCESS BY INDEX ROWID  | CONF_DTL           |     1 |    70 |     1   (0)| 00:00:01 |
    |*  8 |         INDEX RANGE SCAN            | PK_CONF_DTL        |     1 |       |     1   (0)| 00:00:01 |
    |   9 |        BUFFER SORT                  |                    |     1 |    32 |     1   (0)| 00:00:01 |
    |  10 |         SORT UNIQUE                 |                    |     1 |    32 |     1   (0)| 00:00:01 |
    |  11 |          TABLE ACCESS BY INDEX ROWID| CONF_DTL           |     1 |    32 |     1   (0)| 00:00:01 |
    |* 12 |           INDEX RANGE SCAN          | PK_CONF_DTL        |     1 |       |     1   (0)| 00:00:01 |
    |* 13 |       INDEX RANGE SCAN              | SHIP_DTL_IND_6 |     1 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       8 - access("CD"."CONF_NBR"='1')
      12 - access("CONF_NBR"='1')
      13 - access("ITEM_ID"="SD"."ITEM_ID")
           filter("ITEM_ID"="CD"."ITEM_ID")

    Citizen_2 wrote:
    Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??You say that the table stats are up-to-date, but is the following assumption of the optimizer correct:
    select count(*)
    from CONF_dtl
    where CONF_nbr = '1';Does this query return a count of 1? I doubt that, but that's what Oracle estimates in the EXPLAIN PLAN output. Based on that assumption you get a cartesian join between the two CONF_DTL table instances, and the result - which is still expected to be one row at most - is then joined to the SHIP_DTL table using a NESTED LOOP.
    If above assumption is incorrect, the number of rows generated by the cartesian join can be tremendous rendering the NESTED LOOP operation quite inefficient.
    You can verify this by using the DBMS_XPLAN.DISPLAY_CURSOR function together with the GATHER_PLAN_STATISTICS hint, if you're already on 10g or later.
    For more information regarding the DISPLAY_CURSOR function, see e.g. here: http://jonathanlewis.wordpress.com/2006/11/09/dbms_xplan-in-10g/
    It will show you the actual cardinalities compared to the estimated cardinalities.
    If the estimate of the optimizer is incorrect, you should find out why. There still might be some issues with the statistics, since this is most obvious reason for incorrect estimates.
    Are your index statistics up-to-date?
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Query with Explain Plan

    Suppose, i am using two queries [ which are almost equal] but using separate table name aliases. Will this result is separate Explain Plans?
    i.e.
    Explain Plan for : Select * from emp a;
    and Explain for : Select * from emp b;
    Will remain same always, or it will differ?
    Also, i was looking for low level conversion of Parsed SQL statements to Machine Level Language. I mean how this step is performed. Where does the compiler/interpreter resides and how it works.
    Thanks in Advance.
    Regards,
    Sudipta.

    user13513014 wrote:
    Suppose, i am using two queries [ which are almost equal] but using separate table name aliases. Will this result is separate Explain Plans?
    i.e.
    Explain Plan for : Select * from emp a;
    and Explain for : Select * from emp b;
    Will remain same always, or it will differ? By simply switching alias, the optimizer is unlikely to develop a new plan.
    Also, i was looking for low level conversion of Parsed SQL statements to Machine Level Language. I mean how this step is performed. Where does the compiler/interpreter resides and how it works.
    Thanks in Advance.
    Regards,
    Sudipta.There is no way you can actally see the parsing of SQL. It is done internally by oracle in a process caled Hard Parse or Soft Parse. A Hard Parse is where the optimizer must go through all the steps of parsing from the beggining, where as a soft parse, oracle uses the cached results from a hard parsed query that is in the shared pool.
    How the optimizer works is a subject of ample documentation and several books. As a general over view, here are the general steps at parsing an SQL:
    1. Optimizer evaluates your statement, checks it for grammar errors, grants to objects, etc.
    2. Statement Transformation: Optimizer evaluates your statement for possible optimization regarding rewrite, in cases you have view or correlated subqueries.
    3. Choice of optimizer goals.
    4. Choice of acccess paths.
    5. Choice of Join Orders.
    Suggest you try a google search, it will give you a lot of material, or check the Oracle Database Performance Tuning Guide 11.2, which is free by oracle.

  • How to improve the query performance or tune query from Explain Plan

    Hi
    The following is my explain plan for sql query. (The plan is generated by Toad v9.7). How to fix the query?
    SELECT STATEMENT ALL_ROWSCost: 4,160 Bytes: 25,296 Cardinality: 204                                         
         8 NESTED LOOPS Cost: 3 Bytes: 54 Cardinality: 1                                    
              5 NESTED LOOPS Cost: 2 Bytes: 23 Cardinality: 1                               
                   2 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 13 Cardinality: 1                          
                        1 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1                     
                   4 TABLE ACCESS BY INDEX ROWID TABLE AR.HZ_CUST_ACCOUNTS Cost: 1 Bytes: 10 Cardinality: 1                          
                        3 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.HZ_CUST_ACCOUNTS_U1 Cost: 1 Cardinality: 1                     
              7 TABLE ACCESS BY INDEX ROWID TABLE AR.HZ_PARTIES Cost: 1 Bytes: 31 Cardinality: 1                               
                   6 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.HZ_PARTIES_U1 Cost: 1 Cardinality: 1                          
         10 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1                                    
              9 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1                               
         15 NESTED LOOPS Cost: 2 Bytes: 29 Cardinality: 1                                    
              12 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1                               
                   11 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1                          
              14 TABLE ACCESS BY INDEX ROWID TABLE ONT.OE_ORDER_HEADERS_ALL Cost: 1 Bytes: 17 Cardinality: 1                               
                   13 INDEX RANGE SCAN INDEX (UNIQUE) ONT.OE_ORDER_HEADERS_U2 Cost: 1 Cardinality: 1                          
         21 FILTER                                    
              16 TABLE ACCESS FULL TABLE ONT.OE_TRANSACTION_TYPES_TL Cost: 2 Bytes: 1,127 Cardinality: 49                               
              20 NESTED LOOPS Cost: 2 Bytes: 21 Cardinality: 1                               
                   18 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1                          
                        17 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1                     
                   19 INDEX RANGE SCAN INDEX (UNIQUE) ONT.OE_ORDER_HEADERS_U2 Cost: 1 Bytes: 9 Cardinality: 1                          
         23 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1                                    
              22 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1                               
         45 NESTED LOOPS Cost: 4,160 Bytes: 25,296 Cardinality: 204                                    
              42 NESTED LOOPS Cost: 4,150 Bytes: 23,052 Cardinality: 204                               
                   38 NESTED LOOPS Cost: 4,140 Bytes: 19,992 Cardinality: 204                          
                        34 NESTED LOOPS Cost: 4,094 Bytes: 75,850 Cardinality: 925                     
                             30 NESTED LOOPS Cost: 3,909 Bytes: 210,843 Cardinality: 3,699                
                                  26 PARTITION LIST ALL Cost: 2,436 Bytes: 338,491 Cardinality: 14,717 Partition #: 29 Partitions accessed #1 - #18          
                                       25 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_AE_HEADERS Cost: 2,436 Bytes: 338,491 Cardinality: 14,717 Partition #: 29 Partitions accessed #1 - #18     
                                            24 INDEX SKIP SCAN INDEX XLA.XLA_AE_HEADERS_N1 Cost: 264 Cardinality: 1,398,115 Partition #: 29 Partitions accessed #1 - #18
                                  29 PARTITION LIST ITERATOR Cost: 1 Bytes: 34 Cardinality: 1 Partition #: 32           
                                       28 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_AE_LINES Cost: 1 Bytes: 34 Cardinality: 1 Partition #: 32      
                                            27 INDEX RANGE SCAN INDEX (UNIQUE) XLA.XLA_AE_LINES_U1 Cost: 1 Cardinality: 1 Partition #: 32
                             33 PARTITION LIST ITERATOR Cost: 1 Bytes: 25 Cardinality: 1 Partition #: 35                
                                  32 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_DISTRIBUTION_LINKS Cost: 1 Bytes: 25 Cardinality: 1 Partition #: 35           
                                       31 INDEX RANGE SCAN INDEX XLA.XLA_DISTRIBUTION_LINKS_N3 Cost: 1 Cardinality: 1 Partition #: 35      
                        37 PARTITION LIST SINGLE Cost: 1 Bytes: 16 Cardinality: 1 Partition #: 38                     
                             36 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_EVENTS Cost: 1 Bytes: 16 Cardinality: 1 Partition #: 39 Partitions accessed #2               
                                  35 INDEX UNIQUE SCAN INDEX (UNIQUE) XLA.XLA_EVENTS_U1 Cost: 1 Cardinality: 1 Partition #: 40 Partitions accessed #2          
                   41 PARTITION LIST SINGLE Cost: 1 Bytes: 15 Cardinality: 1 Partition #: 41                          
                        40 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_TRANSACTION_ENTITIES Cost: 1 Bytes: 15 Cardinality: 1 Partition #: 42 Partitions accessed #2                    
                             39 INDEX UNIQUE SCAN INDEX (UNIQUE) XLA.XLA_TRANSACTION_ENTITIES_U1 Cost: 1 Cardinality: 1 Partition #: 43 Partitions accessed #2               
              44 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_CODE_COMBINATIONS Cost: 1 Bytes: 11 Cardinality: 1                               
                   43 INDEX UNIQUE SCAN INDEX (UNIQUE) GL.GL_CODE_COMBINATIONS_U1 Cost: 1 Cardinality: 1

    damorgan wrote:
    Tuning is NOT about reducing the cost of i/o.
    i/o is only one of many contributors to cost and only one of many contributors to waits.
    Any time you would like to explore this further run this code:
    SELECT 1 FROM dual
    WHERE regexp_like(' ','^*[ ]*a');but not on a production box because you are going to experience an extreme tuning event with zero i/o.
    And when I say "extreme" I mean "EXTREME!"
    You've been warned.I think you just need a faster server.
    SQL> set autotrace traceonly statistics
    SQL> set timing on
    SQL> select 1 from dual
      2  where
      3  regexp_like   (' ','^*[ ]*a');
    no rows selected
    Elapsed: 00:00:00.00
    Statistics
              1  recursive calls
              0  db block gets
              0  consistent gets
              0  physical reads
              0  redo size
            243  bytes sent via SQL*Net to client
            349  bytes received via SQL*Net from client
              1  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              0  rows processedRepeated from an Oracle 10.2.0.x instance:
    SQL> SELECT DISTINCT SID FROM V$MYSTAT;
           SID
           310
    SQL> ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';
    Session altered.
    SQL> select 1 from dual
      2  where
      3  regexp_like   (' ','^*[ ]*a');The session is hung. Wait a little while and connect to the database using a different session:
    COLUMN STAT_NAME FORMAT A35 TRU
    SET PAGESIZE 200
    SELECT
      STAT_NAME,
      VALUE
    FROM
      V$SESS_TIME_MODEL
    WHERE
      SID=310;
    STAT_NAME                                VALUE
    DB time                                   9247
    DB CPU                                    9247
    background elapsed time                      0
    background cpu time                          0
    sequence load elapsed time                   0
    parse time elapsed                        6374
    hard parse elapsed time                   5997
    sql execute elapsed time                  2939
    connection management call elapsed        1660
    failed parse elapsed time                    0
    failed parse (out of shared memory)          0
    hard parse (sharing criteria) elaps          0
    hard parse (bind mismatch) elapsed           0
    PL/SQL execution elapsed time               95
    inbound PL/SQL rpc elapsed time              0
    PL/SQL compilation elapsed time              0
    Java execution elapsed time                  0
    repeated bind elapsed time                  48
    RMAN cpu time (backup/restore)               0Seems to be using a bit of time for the hard parse (hard parse elapsed time). Wait a little while, then re-execute the query:
    STAT_NAME                                VALUE
    DB time                                   9247
    DB CPU                                    9247
    background elapsed time                      0
    background cpu time                          0
    sequence load elapsed time                   0
    parse time elapsed                        6374
    hard parse elapsed time                   5997
    sql execute elapsed time                  2939
    connection management call elapsed        1660
    failed parse elapsed time                    0
    failed parse (out of shared memory)          0
    hard parse (sharing criteria) elaps          0
    hard parse (bind mismatch) elapsed           0
    PL/SQL execution elapsed time               95
    inbound PL/SQL rpc elapsed time              0
    PL/SQL compilation elapsed time              0
    Java execution elapsed time                  0
    repeated bind elapsed time                  48
    RMAN cpu time (backup/restore)               0The session is not reporting additional CPU usage or parse time.
    Let's check one of the session's statistics:
    SELECT
      SS.VALUE
    FROM
      V$SESSTAT SS,
      V$STATNAME SN
    WHERE
      SN.NAME='consistent gets'
      AND SN.STATISTIC#=SS.STATISTIC#
      AND SS.SID=310;
         VALUE
           163Not many consistent gets after 20+ minutes.
    Let's take a look at the plan:
    SQL> SELECT SQL_ID,CHILD_NUMBER FROM V$SQL WHERE SQL_TEXT LIKE 'select 1 from du
    al%';
    SQL_ID        CHILD_NUMBER
    04mpgrzhsv72w            0
    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('04mpgrzhsv72w',0,'TYPICAL'))
    select 1 from dual where regexp_like   (' ','^*[ ]*a')
    NOTE: cannot fetch plan for SQL_ID: 04mpgrzhsv72w, CHILD_NUMBER: 0
          Please verify value of SQL_ID and CHILD_NUMBER;
          It could also be that the plan is no longer in cursor cache (check v$sql_p
    lan)No plan...
    Let's take a look at the 10053 trace file:
    Registered qb: SEL$1 0x19157f38 (PARSER)
      signature (): qb_name=SEL$1 nbfros=1 flg=0
        fro(0): flg=4 objn=258 hint_alias="DUAL"@"SEL$1"
    Predicate Move-Around (PM)
    PM: Considering predicate move-around in SEL$1 (#0).
    PM:   Checking validity of predicate move-around in SEL$1 (#0).
    CBQT: Validity checks failed for 7uqx4guu04x3g.
    CVM: Considering view merge in query block SEL$1 (#0)
    CBQT: Validity checks failed for 7uqx4guu04x3g.
    Subquery Unnest
    SU: Considering subquery unnesting in query block SEL$1 (#0)
    Set-Join Conversion (SJC)
    SJC: Considering set-join conversion in SEL$1 (#0).
    Predicate Move-Around (PM)
    PM: Considering predicate move-around in SEL$1 (#0).
    PM:   Checking validity of predicate move-around in SEL$1 (#0).
    PM:     PM bypassed: Outer query contains no views.
    FPD: Considering simple filter push in SEL$1 (#0)
    FPD:   Current where clause predicates in SEL$1 (#0) :
              REGEXP_LIKE (' ','^*[ ]*a')
    kkogcp: try to generate transitive predicate from check constraints for SEL$1 (#0)
    predicates with check contraints:  REGEXP_LIKE (' ','^*[ ]*a')
    after transitive predicate generation:  REGEXP_LIKE (' ','^*[ ]*a')
    finally:  REGEXP_LIKE (' ','^*[ ]*a')
    apadrv-start: call(in-use=592, alloc=16344), compile(in-use=37448, alloc=42256)
    kkoqbc-start
                : call(in-use=592, alloc=16344), compile(in-use=38336, alloc=42256)
    kkoqbc-subheap (create addr=000000001915C238)Looks like the query never had a chance to start executing - it is still parsing after 20 minutes.
    I am not sure that this is a good example - the query either executes very fast, or never has a chance to start executing. But, it might still make your point physical I/O is not always the problem when performance problems are experienced.
    Charles Hooper
    IT Manager/Oracle DBA
    K&M Machine-Fabricating, Inc.

  • Understanding meaning of a query's explain plan

    Hi,
    I have a simple query but its query plan is looking difficult for me to understand. Can someone help me explain step by step what happens inthe query. I mean "first step table emp is full scan , than next step is another table's scan..." etc - in that way. I can't make out and need help to understand.
    SQL> explain plan for
      2  SELECT ename,dname ,grade
      3  from n1.salgrade salgrade ,n1.emp emp,n1.dept dept
      4  where emp.deptno=dept.deptno and
      5  emp.sal between salgrade.losal and salgrade.hisal;
    SQL> select plan_table_output from table(dbms_xplan.display());
    Plan hash value: 4131418678
    | Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |          |     1 |    36 |    12  (25)| 00:00:01 |
    |*  1 |  HASH JOIN            |          |     1 |    36 |    12  (25)| 00:00:01 |
    |   2 |   MERGE JOIN          |          |     1 |    23 |     8  (25)| 00:00:01 |
    |   3 |    SORT JOIN          |          |     5 |    50 |     4  (25)| 00:00:01 |
    |   4 |     TABLE ACCESS FULL | SALGRADE |     5 |    50 |     3   (0)| 00:00:01 |
    |*  5 |    FILTER             |          |       |       |            |          |
    |*  6 |     SORT JOIN         |          |    14 |   182 |     4  (25)| 00:00:01 |
    |   7 |      TABLE ACCESS FULL| EMP      |    14 |   182 |     3   (0)| 00:00:01 |
    |   8 |   TABLE ACCESS FULL   | DEPT     |     4 |    52 |     3   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
       5 - filter("EMP"."SAL"<="SALGRADE"."HISAL")
       6 - access("EMP"."SAL">="SALGRADE"."LOSAL")
           filter("EMP"."SAL">="SALGRADE"."LOSAL")for example my question is why there is SORT JOIN on step no 6? does it mean that rows obtained from step 7 are sorted? than what is done during the step of FILTER?why there are so many joins. Basically I am not good in this area so need help.
    Thanks
    Edited by: orausern on Sep 23, 2010 11:58 AM

    The operations are performed in the following order: 4, 3, 7, 6, 5, 2, 8, 1, 0. The Merge Join operation in Node 2 consumes the SALGRADE and EMP records produced by Node 3 and Node 5 respectively. Node 3 and Node 5 are therefore visited repeatedly during the Merge Join operation. Whenever Node 3 produces a SALGRADE record, Node 5 tries to produce matching EMP records. Node 6 produces EMP records that satisfy the condition EMP.SAL >= SALGRADE.LOSAL. Node 5 then checks if the EMP records produced by Node 6 satisfy the additional condition EMP.SAL <= SALGRADE.HISAL before releasing them. All the results of the Merge Join operation are stored in a hash table in memory. Once the construction of the hash table is fully complete, the DEPT table is scanned and each DEPT record is checked using the hash table.
    Iggy

  • Regarding explain plan

    hi all,
    i am using database 10g.
    i have explain as below
    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
    PLAN_TABLE_OUTPUT
    Plan hash value: 2715695103
    | Id  | Operation                     | Name                   | Rows  | Bytes | Cost (%CPU)| Time
       |
    |   0 | SELECT STATEMENT              |                        |     8 |   568 |     6  (17)| 00:00:
    01 |
    |   1 |  HASH UNIQUE                  |                        |     8 |   568 |     6  (17)| 00:00:
    01 |
    |   2 |   NESTED LOOPS                |                        |     8 |   568 |     5   (0)| 00:00:
    01 |
    |*  3 |    TABLE ACCESS FULL          | COMMON_PURCHASE_HEADER |     8 |   232 |     3   (0)| 00:00:
    PLAN_TABLE_OUTPUT
    01 |
    |   4 |    TABLE ACCESS BY INDEX ROWID| CUSTOMER_MASTER        |     1 |    42 |     1   (0)| 00:00:
    01 |
    |*  5 |     INDEX UNIQUE SCAN         | CUM_PK                 |     1 |       |     0   (0)| 00:00:
    01 |
    ----how we can analyse the query based on this plan.
    Thanks..

    What do you think an execution plan is? I think you think that this tells you all by itself how "good" the query is. No that's wrong. You can compare it with the advise a GPS system gives you to go from A to B. Some GPS system give better advices than others, some even know the current traffic situation. But, without any knowledge about the location you are in, you have to trust that plan.
    But, if you live in that area, you might know that another path might me faster than the suggested one,etc.
    All ORACLE tells you with this execution plan, is that it will read table COMMON_PURCHASE_HEADER completely and will join CUSTOMER_MASTER in a nested loop over the PK index.
    WE do now know a lot about your DB, if there are other indexes (e.g. on C_STATUS) and what the cardinality on it is. If there would be an index, and the value A would just occur once, an INDEX lookup might be faster if you would have MUCH moire data!
    On 8 rows....as the optimizer believes all data is on the same block and is read by 1 IO and that's the fastest access.
    So, basically you need to learn what ORACLE tries to do.
    Then you ask yourself, as you know the DB, if that's a clever idea.
    If it's not, ask yourself why ORACLE does not agree with you. It might still be right. So test your access methods with hints, and you will see and learn.
    As I said it's like the advice a GPS system gives you. Only a local can really tell you how clever that suggestion is. (And the local can be wrong) ;-)

  • Is there any way to tune this query? EXPLAIN PLAN included

    DB version:10gR2
    The below query was taking more than 3 seconds. The statistics are up to date for these tables. Is there any other way i could tune this query?
    SELECT COUNT(1)
    FROM
    INVN_SCOPE_DTL, ship_dtl WHERE ship_dtl.WHSE = INVN_SCOPE_DTL.WHSE (+)
    AND 'QC' = INVN_SCOPE_DTL.FROM_WORK_GRP (+)
    AND  'MQN' = INVN_SCOPE_DTL.FROM_WORK_AREA (+)
    AND  ship_dtl.START_CURR_WORK_GRP = INVN_SCOPE_DTL.TO_WORK_GRP (+)
    AND  ship_dtl.START_CURR_WORK_AREA = INVN_SCOPE_DTL.TO_WORK_AREA (+)
    AND  ship_dtl.WHSE = '930' AND  ship_dtl.OWNER_USER_ID = 'CTZDM'
    OR ship_dtl.OWNER_USER_ID = '*'
    AND ship_dtl.STAT_CODE >= '10'
    AND ship_dtl.STAT_CODE <= '20'
    ORDER BY ship_dtl.OWNER_USER_ID DESC,
    ship_dtl.CURR_TASK_PRTY ASC, INVN_SCOPE_DTL.DISTANCE ASC, ship_dtl.RLS_DATE_TIME ASC, ship_dtl.TASK_ID ASC;
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    | Id  | Operation                      |  Name               | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT               |                     |     1 |    86 |    86   (2)|
    |   1 |  SORT AGGREGATE                |                     |     1 |    86 |            |
    |   2 |   NESTED LOOPS OUTER           |                     |   898 | 77228 |    86   (2)|
    |   3 |    INLIST ITERATOR             |                     |       |       |            |
    |*  4 |     TABLE ACCESS BY INDEX ROWID| ship_dtl            |   898 | 31430 |    85   (2)|
    |*  5 |      INDEX RANGE SCAN          | ship_dtl_IND_4      |  2876 |       |     1   (0)|
    |   6 |    TABLE ACCESS BY INDEX ROWID | INVN_SCOPE_DTL     |     1 |    51 |     2  (50)|
    PLAN_TABLE_OUTPUT
    |*  7 |     INDEX UNIQUE SCAN          | PK_INVN_SCOPE_DTL  |     1 |       |            |
    Predicate Information (identified by operation id):
       4 - filter("ship_dtl"."WHSE"='930' AND "ship_dtl"."STAT_CODE">=10 AND
                  "ship_dtl"."STAT_CODE"<=20)
       5 - access("ship_dtl"."OWNER_USER_ID"='*' OR "ship_dtl"."OWNER_USER_ID"='CTZDM')
       7 - access("INVN_SCOPE_DTL"."WHSE"(+)='930' AND
                  "INVN_SCOPE_DTL"."FROM_WORK_GRP"(+)='QC' AND "INVN_SCOPE_DTL"."FROM_WORK_AREA"(+)='MQN'
    PLAN_TABLE_OUTPUT
                  AND "ship_dtl"."START_CURR_WORK_GRP"="INVN_SCOPE_DTL"."TO_WORK_GRP"(+) AND
                  "ship_dtl"."START_CURR_WORK_AREA"="INVN_SCOPE_DTL"."TO_WORK_AREA"(+))
           filter("ship_dtl"."WHSE"="INVN_SCOPE_DTL"."WHSE"(+))
    25 rows selected.

    William Robertson wrote:
    I notice an OR predicate in the middle of some AND predicates without explicit bracketing. Are you sure it does what you think it does?I underline this point.
    A conjuction (AND expression) has a higher priority and will be executed (logically) before the disjunction (OR expression)! So your select looks like this
    SELECT COUNT(1)
    FROM INVN_SCOPE_DTL, ship_dtl
    WHERE
          ( ship_dtl.WHSE = INVN_SCOPE_DTL.WHSE (+)
          AND 'QC' = INVN_SCOPE_DTL.FROM_WORK_GRP (+)
          AND  'MQN' = INVN_SCOPE_DTL.FROM_WORK_AREA (+)
          AND  ship_dtl.START_CURR_WORK_GRP = INVN_SCOPE_DTL.TO_WORK_GRP (+)
          AND  ship_dtl.START_CURR_WORK_AREA = INVN_SCOPE_DTL.TO_WORK_AREA (+)
          AND  ship_dtl.WHSE = '930'
          AND  ship_dtl.OWNER_USER_ID = 'CTZDM'
    OR   ( ship_dtl.OWNER_USER_ID = '*'
          AND ship_dtl.STAT_CODE >= '10'
          AND ship_dtl.STAT_CODE <= '20'
    ;This might be want you want, but I doubt it very much. Please add parenthesis', to get it working the way it should be.
    Edited by: Sven W. on Oct 16, 2008 3:25 PM

  • How i can obtain explain plan without run the query

    Hello,
    i need to know the result of explain of a query without run the query, it's this possible?
    Thanks and best regards.

    explain plan for <your query>;
    select * from table(dbms_xplan.display);Regards,
    Rob.

  • Query Explain Plan Help

    I am running the following query against my database
    SELECT p.ID
      FROM rap_counterparties cou,
           rap_presentation_cou_ratings pcr,
           rap_presentation_states sta,
           rap_app_user_profiles aup,
           rap_presentations p
    WHERE cou.unt_id = aup.unt_id
       AND aup.aur_id = 7529
       AND pcr.cou_id = cou.ID
       AND sta.cur_present_state_instance_flg = 'Y'
       AND sta.state_type_id = pcr.pst_state_type_id
       AND sta.pre_id = pcr.pst_pre_id
       AND sta.state_type_id IN (326, 322, 323, 324, 325)
       AND cou.unt_id = p.unt_id
       AND p.ID = sta.pre_id
       AND (   p.private_flg != 'Y'
            OR (p.private_flg = 'Y' AND p.created_by_user_id = 10000083)
    Explain plan of the query is
    PLAN_TABLE_OUTPUT
    | Id  | Operation                        |  Name                  | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                 |                        |     8 |   456 |  3936  (16)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID     | RAP_PRESENTATIONS      |     1 |    15 |     2  (50)|
    |   2 |   NESTED LOOPS                   |                        |     8 |   456 |  3936  (16)|
    |*  3 |    HASH JOIN                     |                        |  1745 | 73290 |  2145  (27)|
    |*  4 |     HASH JOIN                    |                        | 14257 |   431K|  1299  (25)|
    |*  5 |      HASH JOIN                   |                        |  5173 | 87941 |   583  (16)|
    |   6 |       TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES  |    18 |   144 |     3  (34)|
    |*  7 |        INDEX RANGE SCAN          | RAP_AUP_IX_01          |    18 |       |     2  (50)|
    |   8 |       TABLE ACCESS FULL          | RAP_COUNTERPARTIES     |   118K|  1042K|   560  (13)|
    |*  9 |      INDEX FAST FULL SCAN        | RAP_PCR_PK             |   326K|  4467K|   659  (25)|
    |* 10 |     INDEX FAST FULL SCAN         | RAP_PST_IX_02          |   120K|  1291K|   821  (29)|
    |* 11 |    INDEX RANGE SCAN              | RAP_PRE_PK             |     1 |       |            |
    Predicate Information (identified by operation id):
       1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."CREATED_BY_USER_ID"=10000083 AND
                  "P"."PRIVATE_FLG"='Y') AND "COU"."UNT_ID"="P"."UNT_ID")
       3 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
                  "STA"."PRE_ID"="PCR"."PST_PRE_ID")
       4 - access("PCR"."COU_ID"="COU"."ID")
       5 - access("COU"."UNT_ID"="AUP"."UNT_ID")
       7 - access("AUP"."AUR_ID"=7529)
       9 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
                  "PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
      10 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
                  "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
                  "STA"."STATE_TYPE_ID"=326))
      11 - access("P"."ID"="STA"."PRE_ID")
    Table Row count
    rap_app_user_profiles : 30639
    rap_counterparties : 118583
    rap_presentation_cou_ratings -- 652781
    rap_presentation_states -- 982413
    rap_presentations -- 246145
    Questions
    1. Why is the index not being used on the table rap_counterparties. If I force a hint then the index is being used
    2. Is there a way I can have an index range scan as opposed to the index fast full scan.
    3. This query runs in 3s. Is there anything else I can do to tune this query?
    4. In predicate 9 and 10 the two tables have fast full scan. If the filter of unit generates only a few records why can't those few records be joined with these tables. Why the whole tables are first being scanned and then joined
    Appreciate your response

    Thanks for the suggestions.
    So I tried using the FIRST_ROW HINT and i am getting the nested loops join and it runs fast in 250ms.
    SELECT /*+FIRST_ROWS*/
           p.ID ID
      FROM rap_presentations p,
           rap_counterparties cou,
           rap_presentation_states sta,
           rap_presentation_cou_ratings pcr
    WHERE cou.unt_id IN (
               SELECT prof.unt_id
                 FROM rap_application_users u, rap_app_user_profiles prof
                WHERE u.ID = prof.aur_id AND u.ID = 7529
                      AND prof.aro_id NOT IN (8))
       AND cou.unt_id = p.unt_id
       AND p.ID = sta.pre_id
       AND sta.cur_present_state_instance_flg = 'Y'
       AND sta.state_type_id = pcr.pst_state_type_id
       AND sta.pre_id = pcr.pst_pre_id
       AND pcr.cou_id = cou.ID
       AND (   p.private_flg != 'Y'
            OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
       AND sta.state_type_id IN (326, 322, 323, 324, 325)
    Explain plan:
    PLAN_TABLE_OUTPUT
    | Id  | Operation                           |  Name                         | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                    |                               |     7 |   434 | 43334   (2)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID        | RAP_PRESENTATIONS             |     1 |    15 |     2  (50)|
    |   2 |   NESTED LOOPS                      |                               |     7 |   434 | 43334   (2)|
    |   3 |    NESTED LOOPS                     |                               |  1593 | 74871 | 41699   (2)|
    |   4 |     NESTED LOOPS                    |                               | 13016 |   457K| 15196   (2)|
    |   5 |      NESTED LOOPS                   |                               |  4723 |   101K|   798   (2)|
    |   6 |       VIEW                          | VW_NSO_1                      |    16 |   208 |            |
    |   7 |        SORT UNIQUE                  |                               |    16 |   256 |            |
    |   8 |         NESTED LOOPS                |                               |    16 |   256 |     4  (25)|
    |*  9 |          INDEX UNIQUE SCAN          | RAP_AUR_PK                    |     1 |     5 |     2  (50)|
    |* 10 |          TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES         |    16 |   176 |     3  (34)|
    |* 11 |           INDEX RANGE SCAN          | RAP_AUP_IX_01                 |    18 |       |     2  (50)|
    |  12 |       TABLE ACCESS BY INDEX ROWID   | RAP_COUNTERPARTIES            |   295 |  2655 |    50   (2)|
    |* 13 |        INDEX RANGE SCAN             | RAP_COU_IX_02                 |    95 |       |     2  (50)|
    |* 14 |      TABLE ACCESS BY INDEX ROWID    | RAP_PRESENTATION_COU_RATINGS  |     3 |    42 |     4  (25)|
    |* 15 |       INDEX RANGE SCAN              | RAP_PCR_IX_03                 |    10 |       |     3  (34)|
    |* 16 |     INDEX RANGE SCAN                | RAP_PST_IX_02                 |     1 |    11 |     3  (34)|
    |* 17 |    INDEX RANGE SCAN                 | RAP_PRE_PK                    |     1 |       |            |
    Predicate Information (identified by operation id):
       1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529) AND
                  "COU"."UNT_ID"="P"."UNT_ID")
       9 - access("U"."ID"=7529)
      10 - filter("PROF"."ARO_ID"<>8)
      11 - access("PROF"."AUR_ID"=7529)
      13 - access("COU"."UNT_ID"="VW_NSO_1"."$nso_col_1")
      14 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
                  "PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
      15 - access("PCR"."COU_ID"="COU"."ID")
      16 - access("STA"."PRE_ID"="PCR"."PST_PRE_ID" AND "STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
                  "STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
           filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR
                  "STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
      17 - access("P"."ID"="STA"."PRE_ID")
    But my query that runs to get the data has a union with another query and with the change it looks like below
    SELECT /*+FIRST_ROWS*/
           p.ID ID
      FROM rap_presentations p,
           rap_counterparties cou,
           rap_presentation_states sta,
           rap_presentation_cou_ratings pcr
    WHERE cou.unt_id IN (
               SELECT prof.unt_id
                 FROM rap_application_users u, rap_app_user_profiles prof
                WHERE u.ID = prof.aur_id AND u.ID = 7529
                      AND prof.aro_id NOT IN (8))
       AND cou.unt_id = p.unt_id
       AND p.ID = sta.pre_id
       AND sta.cur_present_state_instance_flg = 'Y'
       AND sta.state_type_id = pcr.pst_state_type_id
       AND sta.pre_id = pcr.pst_pre_id
       AND pcr.cou_id = cou.ID
       AND (   p.private_flg != 'Y'
            OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
       AND sta.state_type_id IN (326, 322, 323, 324, 325)
    UNION
    SELECT /*+index(pfs)*/
           p.ID ID
      FROM rap_presentations p,
           rap_presentation_states sta,
           rap_facilities f,
           rap_presentation_fac_states pfs
    WHERE f.unt_id IN (
               SELECT prof.unt_id
                 FROM rap_application_users u, rap_app_user_profiles prof
                WHERE u.ID = prof.aur_id AND u.ID = 7529
                      AND prof.aro_id NOT IN (8))
       AND f.unt_id = p.unt_id
       AND p.ID = sta.pre_id
       AND sta.cur_present_state_instance_flg = 'Y'
       AND sta.state_type_id = pfs.pst_state_type_id
       AND sta.pre_id = pfs.pst_pre_id
       AND pfs.fac_id = f.ID
       AND pfs.fac_num = f.num
       AND f.current_facility_instance_flg = 'Y'
       AND (   p.private_flg != 'Y'
            OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
       AND sta.state_type_id IN (326, 322, 323, 324, 325)
    Explain plan :
    PLAN_TABLE_OUTPUT
    | Id  | Operation                          |  Name                  | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                   |                        |     8 |   534 | 14931  (80)|
    |   1 |  SORT UNIQUE                       |                        |     8 |   534 | 14931  (80)|
    |   2 |   UNION-ALL                        |                        |       |       |            |
    |*  3 |    TABLE ACCESS BY INDEX ROWID     | RAP_PRESENTATIONS      |     1 |    15 |     2  (50)|
    |   4 |     NESTED LOOPS                   |                        |     7 |   455 |  3728  (17)|
    |*  5 |      HASH JOIN                     |                        |  1542 | 77100 |  2145  (27)|
    |*  6 |       HASH JOIN                    |                        | 12598 |   479K|  1300  (24)|
    |*  7 |        HASH JOIN                   |                        |  4571 |   111K|   584  (16)|
    |*  8 |         TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES  |    16 |   176 |     3  (34)|
    |*  9 |          INDEX RANGE SCAN          | RAP_AUP_IX_01          |    18 |       |     2  (50)|
    |  10 |         NESTED LOOPS               |                        |   118K|  1621K|   561  (13)|
    |* 11 |          INDEX UNIQUE SCAN         | RAP_AUR_PK             |     1 |     5 |     2  (50)|
    |  12 |          TABLE ACCESS FULL         | RAP_COUNTERPARTIES     |   118K|  1042K|   560  (13)|
    |* 13 |        INDEX FAST FULL SCAN        | RAP_PCR_PK             |   326K|  4467K|   659  (25)|
    |* 14 |       INDEX FAST FULL SCAN         | RAP_PST_IX_02          |   120K|  1291K|   821  (29)|
    |* 15 |      INDEX RANGE SCAN              | RAP_PRE_PK             |     1 |       |            |
    |  16 |    NESTED LOOPS                    |                        |     1 |    79 | 11201   (2)|
    |  17 |     NESTED LOOPS                   |                        |    75 |  4800 | 11124   (2)|
    |  18 |      NESTED LOOPS                  |                        |   617 | 32701 |  9867   (2)|
    |  19 |       NESTED LOOPS                 |                        |  2104 | 69432 |  5606   (2)|
    |  20 |        NESTED LOOPS                |                        |    16 |   256 |     4  (25)|
    |* 21 |         INDEX UNIQUE SCAN          | RAP_AUR_PK             |     1 |     5 |     2  (50)|
    |* 22 |         TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES  |    16 |   176 |     3  (34)|
    |* 23 |          INDEX RANGE SCAN          | RAP_AUP_IX_01          |    18 |       |     2  (50)|
    |* 24 |        TABLE ACCESS BY INDEX ROWID | RAP_FACILITIES         |   135 |  2295 |   351   (2)|
    |* 25 |         INDEX RANGE SCAN           | RAP_FAC_IX_02          |  1608 |       |     5  (20)|
    |* 26 |       INDEX RANGE SCAN             | RAP_PFR_PK             |     1 |    20 |     3  (34)|
    |* 27 |      INDEX RANGE SCAN              | RAP_PST_IX_02          |     1 |    11 |     3  (34)|
    |* 28 |     TABLE ACCESS BY INDEX ROWID    | RAP_PRESENTATIONS      |     1 |    15 |     2  (50)|
    |* 29 |      INDEX UNIQUE SCAN             | RAP_PRE_PK             |     1 |       |            |
    Predicate Information (identified by operation id):
       3 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
                  AND "COU"."UNT_ID"="P"."UNT_ID")
       5 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
                  "STA"."PRE_ID"="PCR"."PST_PRE_ID")
       6 - access("PCR"."COU_ID"="COU"."ID")
       7 - access("COU"."UNT_ID"="PROF"."UNT_ID")
       8 - filter("PROF"."ARO_ID"<>8)
       9 - access("PROF"."AUR_ID"=7529)
      11 - access("U"."ID"=7529)
      13 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
                  "PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
      14 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
                  "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
                  "STA"."STATE_TYPE_ID"=326))
      15 - access("P"."ID"="STA"."PRE_ID")
      21 - access("U"."ID"=7529)
      22 - filter("PROF"."ARO_ID"<>8)
      23 - access("PROF"."AUR_ID"=7529)
      24 - filter("F"."CURRENT_FACILITY_INSTANCE_FLG"='Y')
      25 - access("F"."UNT_ID"="PROF"."UNT_ID")
      26 - access("PFS"."FAC_ID"="F"."ID" AND "PFS"."FAC_NUM"="F"."NUM")
           filter("PFS"."PST_STATE_TYPE_ID"=322 OR "PFS"."PST_STATE_TYPE_ID"=323 OR
                  "PFS"."PST_STATE_TYPE_ID"=324 OR "PFS"."PST_STATE_TYPE_ID"=325 OR "PFS"."PST_STATE_TYPE_ID"=326)
      27 - access("STA"."PRE_ID"="PFS"."PST_PRE_ID" AND
                  "STA"."STATE_TYPE_ID"="PFS"."PST_STATE_TYPE_ID" AND "STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
           filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324
                  OR "STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
      28 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
                  AND "F"."UNT_ID"="P"."UNT_ID")
      29 - access("P"."ID"="STA"."PRE_ID")
    Question:
    1. When I put the query with the FIRST_ROWS hint in a union with another query, the explain plan reverts back to the older explain plan. how can I avoid it when running by iteslf it runs really quick?
    2. Why is the cost with nested loops more higher? Is it because of statistics?
    2. Does the database parameter db_multiblock_read_count have any affect  on the fast full scan?
    3. I gather statistics using the followin method
    begin
       dbms_stats.gather_schema_stats(
          ownname          => 'RAP_OWNER',
          estimate_percent => dbms_stats.auto_sample_size,
          method_opt       => 'for all columns size auto',
          degree           => 7
    end;
    Sometimes I also use the following method
    BEGIN
    dbms_stats.gather_schema_stats( ownname=>'RAP_OWNER',
    METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE SKEWONLY',
    CASCADE=>TRUE, ESTIMATE_PERCENT=>100);
    END;
    Which one is good or should I use both?
    Appreciate your input.

  • Cpu time is not getting displayed in explain plan

    Hi All,
    I am trying to analyze one query using explain plan .like below
    1) explain plan for
    SELECT /*+ parallel(tsp,8) use_hash( tsp tp) */ count(1)
    FROM router tp,
    receiver tsp
    WHERE tp.rs = tsp.rp
    AND creater_date >=to_date('04032009000000','ddmmyyyyhh24miss')
    and tsp.XVF is not null
    and tp.XVF is not null
    and tp.role_name='BR';
    2)@$ORACLE_HOME/rdbms/admin/utlxpls.sql
    But i am getting only following columns in result .
    | Id | Operation | Name | Rows | Bytes | Cost |
    No Cpu time preset .
    How can i extimate CPU time ?
    Pls help
    Thanks

    am_73798 wrote:
    I am trying to analyze one query using explain plan .like below
    But i am getting only following columns in result .
    | Id | Operation | Name | Rows | Bytes | Cost |
    No Cpu time preset .
    How can i extimate CPU time ?You need to mention your database version (4-digits, e.g. 9.2.0.8).
    In Oracle 9i CPU costing is disabled by default, you need to gather WORKLOAD system statistics to enable the CPU costing.
    In 10g CPU costing is enabled by default and uses default NOWORKLOAD system statistics if no WORKLOAD system statistics have been gathered. It can only be disabled by setting an undocumented parameter or by changing the OPTIMIZER_FEATURES_ENABLE parameter back to 9i compatibility.
    You can check the status of your system statistics by running the following query in SQL*Plus:
    column sname format a20
    column pname format a20
    column pval2 format a20
    select
    sname
    , pname
    , pval1
    , pval2
    from
    sys.aux_stats$;Can you show us the actual (complete) output you get from "utlxpls.sql"? Use the \ tag to preserve formatting here:
    \output
    \will show asoutput
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Filter(NULL IS NOT NULL) in Explain Plan ??

    Hi All,
    Can someone please explain what this explain plan statement means? I see a filter(NULL IS NOT NULL) as the first statement - could not figure out why it came up so from googling.
    My Query Used:
    EXPLAIN PLAN FOR
    MERGE INTO summary_bysrccd
    USING
    (SELECT LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS SUMMARY_DATE,
    os.acctnum,
    ol.sourcecode AS sourcecode,
    ol.sourcename AS sourcename,
    count(1) cnt_articleview
    FROM article_views os , master_sourcecode ol
    where os.sourcecode = ol.sourcecode
    AND os.acctnum IS NOT NULL
    AND ol.sourcecode IS NOT NULL
    AND os.requestdatetime IS NOT NULL
    AND UPPER(os.success_ind) = 'S'
         AND (
              ('INCR'  = 'FULL'
              AND  (get_date_timestamp(os.requestdatetime) BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS')
              AND   os.entry_CreatedDate BETWEEN TO_DATE('22-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('28-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
              OR ('INCR' = 'FULL'
              AND os.entry_createddate BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS') )
    group by LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))),
    os.acctnum,ol.sourcecode,ol.sourcename) mrg_query
    ON (ods_av_summary_bysrccd.acctnum = mrg_query.acctnum AND
    ods_av_summary_bysrccd.summary_date=mrg_query.summary_date AND
    ods_av_summary_bysrccd.sourcecode=mrg_query.sourcecode)
    WHEN NOT MATCHED THEN
    INSERT (SUMMARY_date,ACCTNUM,SOURCECODE,SOURCENAME,CNT_ARTICLEVIEW,ENTRY_LASTUPDATEDDATE)
    VALUES(mrg_query.summary_date,mrg_query.acctnum,mrg_query.sourcecode,mrg_query.sourcename,
    mrg_query.cnt_articleview,sysdate)
    WHEN MATCHED THEN
    UPDATE SET ods_av_summary_bysrccd.cnt_articleview=
    CASE WHEN NVL('INCR','INCR') = 'FULL' THEN mrg_query.cnt_articleview
    ELSE ods_av_summary_bysrccd.cnt_articleview+mrg_query.cnt_articleview
    END,
    ods_av_summary_bysrccd.entry_lastupdateddate=sysdate;My Explain Plan:
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 268591246
    | Id  | Operation                                 | Name                      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | MERGE STATEMENT                           |                           |     1 |   456 |       |     3   (0)| 00:00:01 |       |       |
    |   1 |  MERGE                                    | ODS_AV_SUMMARY_BYSRCCD    |       |       |       |            |          |       |       |
    |   2 |   VIEW                                    |                           |       |       |       |            |          |       |       |
    |   3 |    NESTED LOOPS OUTER                     |                           |     1 |   417 |       |     3   (0)| 00:00:01 |       |       |
    |   4 |     VIEW                                  |                           |     1 |   360 |       |     5 (100)| 00:00:01 |       |       |
    |   5 |      SORT GROUP BY                        |                           |     1 |    73 |   595M|            |          |       |       |
    PLAN_TABLE_OUTPUT
    |*  6 |       FILTER                              |                           |       |       |       |            |          |       |       |
    |*  7 |        HASH JOIN                          |                           |  6975K|   485M|  3944K| 17594   (1)| 00:03:32 |       |       |
    |   8 |         TABLE ACCESS FULL                 | ODS_MASTER_SOURCECODE     | 84021 |  2953K|       |   273   (1)| 00:00:04 |       |       |
    |*  9 |         TABLE ACCESS BY GLOBAL INDEX ROWID| ODS_ARTICLE_VIEWS         |  7007K|   247M|       |   826   (0)| 00:00:10 |    33 |    33 |
    |* 10 |          INDEX FULL SCAN                  | IDX_AV_ACCTNUM            |    25M|       |       |    26   (0)| 00:00:01 |       |       |
    |  11 |     TABLE ACCESS BY GLOBAL INDEX ROWID    | ODS_AV_SUMMARY_BYSRCCD    |     1 |    57 |       |     3   (0)| 00:00:01 | ROWID | ROWID |
    |* 12 |      INDEX UNIQUE SCAN                    | ODS_AV_SUMMARY_BYSRCCD_PK |     1 |       |       |     2   (0)| 00:00:01 |       |       |
    Predicate Information (identified by operation id):
    PLAN_TABLE_OUTPUT
       6 - filter(NULL IS NOT NULL)
       7 - access("OS"."SOURCECODE"="OL"."SOURCECODE")
       9 - filter("OS"."REQUESTDATETIME" IS NOT NULL AND "OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-08-23 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE(' 2011-08-27 23:59:59', 'syyyy-mm-dd hh24:mi:ss') AND UPPER("OS"."SUCCESS_IND")='S')
      10 - filter("OS"."ACCTNUM" IS NOT NULL)
      12 - access("ODS_AV_SUMMARY_BYSRCCD"."SUMMARY_DATE"(+)=INTERNAL_FUNCTION("MRG_QUERY"."SUMMARY_DATE") AND
                  "ODS_AV_SUMMARY_BYSRCCD"."ACCTNUM"(+)="MRG_QUERY"."ACCTNUM" AND "ODS_AV_SUMMARY_BYSRCCD"."SOURCECODE"(+)="MRG_QUERY"."SOURCECODE")
    Note
    PLAN_TABLE_OUTPUT
       - dynamic sampling used for this statement

    Hi Toon,
    Thanks for the quick resolution. I went back and verified the table's colunm details and it has a NOT NULL constraint.
    Regards,
    Chaitanya
    P.S: Is it ok if I ask you for some help regarding a production issue I have been encountering since 15 days but haev no clear resolution yet about what/why is the reason (the said issue is neither uniform nor regular - its affecting some modules and happening on some days - i shall give the full details if you are willing to have a look) - i shall start a new post or email you directly - yur convenience.

  • Time column of an explain plan

    Hi,
    I'm using Oracle version 10.2.0.3.0. I have 2 tables with 10 million records each. The DDL is as follows.
    create table bigtable(col1 varchar2(20), col2 varchar2(20))
    create table bigtablechild(col1 varchar2(20), col2 varchar(20))
    bigtablechild.col1 is a foreign key to bigtable.col1. Below is the query and explain plan. Over several executions, the query runs for about 20 seconds before returning results. Could anyone please explain what the time column represents? It doesn't match the time it took to return results.
    SQL> set autotrace on
    SQL>
    SQL> select b.col2
      2  from bigtable a, bigtablechild b
      3  where a.col1 = b.col1
      4  and a.col1 = 'ABC6554';
    COL2
    XYZ6554
    XYZ6554
    XYZ6554
    XYZ6554
    XYZ6554
    Execution Plan
    Plan hash value: 4210396901
    | Id  | Operation          | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |               |     5 |   150 | 21538   (4)| 00:04:19 |
    |*  1 |  HASH JOIN         |               |     5 |   150 | 21538   (4)| 00:04:19 |
    |*  2 |   TABLE ACCESS FULL| BIGTABLE      |     1 |    10 | 13124   (4)| 00:02:38 |
    |*  3 |   TABLE ACCESS FULL| BIGTABLECHILD |     5 |   100 |  8413   (5)| 00:01:41 |
    Predicate Information (identified by operation id):
       1 - access("A"."COL1"="B"."COL1")
       2 - filter("A"."COL1"='ABC6554')
       3 - filter("B"."COL1"='ABC6554')
    Statistics
              0  recursive calls
              0  db block gets
          93672  consistent gets
          91845  physical reads
              0  redo size
            463  bytes sent via SQL*Net to client
            396  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              5  rows processed

    Hi,
    the values in the TIME column are calculated from cost using system I/O statistics. If dbms_stats.gather_system_stats has never been run, then these stats have default values which may be very far from the truth. In your case, the optimizer expects a single-block I/O read to take about 12 ms, while in reality it is closer to 1 ms, thus the discrepancy between the prediction and actual results.
    In general, TIME column is not very helpful not just because of potentially incorrect I/O time estimates, but also because it is hard to predict how much data will be found in cash, so I would recommend not to pay too much attention to it (note, however, that A-time column, on the other hand, is extremely useful, but it's only available if rowsource statistics for the plan have been populated).
    Best regards,
    Nikolay

Maybe you are looking for