Explain Plan Cache?

How do you flush the Explain Plan Cache on Oracle 10g?

Do you refer to the contents of these views?
V$SQLAREA_PLAN_HASH
V$SQL_PLAN
V$SQL_PLAN_STATISTICS
V$SQL_PLAN_STATISTICS_ALL
If this is the case, those cannot be flushed but by an instance restart.
If you mean flushing the library cache, then this can be achieved by means of the command:
ALTER SYSTEM FLUSH SHARED POOL;
~ Madrid
http://hrivera99.blogspot.com/

Similar Messages

  • Explain plans - caching question

    I am trying to get some explain plan information for some queries that we have running poorly. Our application uses some alter session statements to set the optimizer_mode to all_rows. I am trying to determine if we need to include the optimizer_index_cost_adj parameter and possibly the optimizer_index_caching parameter.
    Using SQL Developer I can easily run the different alter session statements needed and then get an explain plan for the query in question. However I am seeing some weird results - for example long query times for queries that have a relatively low cost. On the flip side I am seeing some queries that have a higher cost return quicker.
    I am doing this many times over and am wondering what impact using the same query could have. Is this query being cached in Oracle? To get an accurate explain plan would I need to clear a cache each time?
    Also, in the explain plan is the cost figure the most important? How is it that a query can have a low cost and take longer to complete than the same query with a higher cost and some different parameters?

    There are no fixed road map for what to see in explain plan,but some common observation should be made for explain plan i.e full table scans due to poor use of indexing,inappropriate hints uses for forcing indexing where FTS can be faster.unnecessary sorting,cartesian
    joins, outer joins, and anti-joins.
    At last i would say that every database vary to its different hardware platforms and those hardware have different configuration,these things can effect oracle optimizer.
    So, if my statistics are current, what should I be
    taking out of the explain plan? I always assumed
    cost was the main indicator of the performance of a
    query.As justin already told cost is not something which should be considered for tuning query rather access path, but there is more other then explain plan access path e.g TKPROF tool which will address you plan as well as others stuff which should be considered for tuning query.
    http://download.oracle.com/docs/cd/B10501_01/server.920/a96533/sqltrace.htmKhurram

  • Explain plan results are different in SQL Developer than SQL Plus

    My Environment:
    SQL Developer 1.0.0.15.27
    Platform where SQL Developer is running: Windows XP 2002 SP2
    Oracle Database and Client 9.2.0.7
    Optimizer_mode: FIRST_ROWS
    I have the following SQL statement:
    SELECT a1.comp_id
    FROM temp_au_company a0, au_company a1
    WHERE :b2 = a0.temp_emp_code
    AND a0.comp_id = a1.comp_id
    AND a0.sls_terr_code != a1.sls_terr_code
    AND a1.last_mdfy_date > :b1
    When I run an Explain in SQL Developer I get the following access path (which is the one I really want):
    SELECT STATEMENT                          TABLE ACCESS(BY INDEX ROWID) FEDLINK.AU_COMPANY          NESTED LOOPS                                   INDEX(RANGE SCAN)
    FEDLINK.UX2_TEMP_AU_COMPANY
              INDEX(RANGE SCAN) FEDLINK.PX1_COMPANY
    However, when I execute the statement with sql_trace turned on and use tkprof to generate the actual access path, the statement executes as follows (which is WAY more expensive):
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 0.00 0.00 0 0 0 0
    Fetch 1 3.58 6.68 28136 29232 0 0
    total 3 3.58 6.69 28136 29232 0 0
    Misses in library cache during parse: 1
    Optimizer goal: FIRST_ROWS
    Parsing user id: 979 (FEDLINK) (recursive depth: 1)
    Rows Row Source Operation
    0 NESTED LOOPS
    0 TABLE ACCESS FULL AU_COMPANY
    0 INDEX RANGE SCAN UX2_TEMP_AU_COMPANY (object id 49783)
    Notice the FULL access of au_company.
    I understand that SQL Developer has nothing to do with why the statement executed the way it did, but why is the Explain in SQL Developer different than the actual execution plan?
    Added note....when I run the explain in SQL Plus it is the same as the actual execution. Here is the explain from SQL Plus:
    explain plan for SELECT a1.comp_id
    FROM temp_au_company a0, au_company a1
    WHERE '1' = a0.temp_emp_code
    AND a0.comp_id = a1.comp_id
    AND a0.sls_terr_code != a1.sls_terr_code
    AND a1.last_mdfy_date > '01-MAY-2006';
    PLAN_TABLE_OUTPUT
    | Id | Operation | Name | Rows | Bytes | Cost |
    | 0 | SELECT STATEMENT | | 2 | 76 | 2597 |
    | 1 | NESTED LOOPS | | 2 | 76 | 2597 |
    | 2 | TABLE ACCESS FULL | AU_COMPANY | 2 | 42 | 2595 |
    | 3 | INDEX RANGE SCAN | UX2_TEMP_AU_COMPANY | 1 | 17 | 2
    Thanks,
    Brenda

    The explain is different (full scan of au_company in SQL Plus / index access in SQL Developer) even when I use variables in SQL Plus. Here is the output for SQL Plus using variables instead of literals:
    SQL> variable b1 varchar2
    SQL> variable b2 char
    SQL> explain plan for SELECT a1.comp_id
    2 FROM temp_au_company a0, au_company a1
    3 WHERE :b2 = a0.temp_emp_code
    4 AND a0.comp_id = a1.comp_id
    5 AND a0.sls_terr_code != a1.sls_terr_code
    6 AND a1.last_mdfy_date > :b1
    7 /
    Explained.
    PLAN_TABLE_OUTPUT
    | Id | Operation | Name | Rows | Bytes | Cost |
    | 0 | SELECT STATEMENT | | 3184 | 118K| 2995 |
    | 1 | HASH JOIN | | 3184 | 118K| 2995 |
    | 2 | INDEX RANGE SCAN | UX2_TEMP_AU_COMPANY | 3187 | 54179 | 3 |
    | 3 | TABLE ACCESS FULL | AU_COMPANY | 24009 | 492K| 2983 |
    Any other ideas? They should be the same.
    Brenda

  • Performance problem: Query explain plan changes in pl/sql vs. literal args

    I have a complex query with 5+ table joins on large (million+ row) tables. In it's most simplified form, it's essentially
    select * from largeTable large
    join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
    join...(other aux tables)
    where large.pk_id between 123 and 456;
    Its performance was excellent with literal arguments (1 sec per execution).
    But, when I used pl/sql bind argument variables instead of 123 and 456 as literals, the explain plan changes drastically, and runs 10+ minutes.
    Ex:
    CREATE PROCEDURE runQuery(param1 INTEGER, param2 INTEGER){
    CURSOR LT_CURSOR IS
    select * from largeTable large
    join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
    join...(other aux tables)
    where large.pk_id between param1 AND param2;
    BEGIN
    FOR aRecord IN LT_CURSOR
    LOOP
    (print timestamp...)
    END LOOP;
    END runQuery;
    Rewriting the query 5 different ways was unfruitful. DB hints were also unfruitful in this particular case. LargeTable.pk_id was an indexed field as were all other join fields.
    Solution:
    Lacking other options, I wrote a literal query that concatenated the variable args. Open a cursor for the literal query.
    Upside: It changed the explain plan to the only really fast option and performed at 1 second instead of 10mins.
    Downside: Query not cached for future use. Perfectly fine for this query's purpose.
    Other suggestions are welcome.

    AmandaSoosai wrote:
    I have a complex query with 5+ table joins on large (million+ row) tables. In it's most simplified form, it's essentially
    select * from largeTable large
    join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
    join...(other aux tables)
    where large.pk_id between 123 and 456;
    Its performance was excellent with literal arguments (1 sec per execution).
    But, when I used pl/sql bind argument variables instead of 123 and 456 as literals, the explain plan changes drastically, and runs 10+ minutes.
    Ex:
    CREATE PROCEDURE runQuery(param1 INTEGER, param2 INTEGER){
    CURSOR LT_CURSOR IS
    select * from largeTable large
    join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
    join...(other aux tables)
    where large.pk_id between param1 AND param2;
    BEGIN
    FOR aRecord IN LT_CURSOR
    LOOP
    (print timestamp...)
    END LOOP;
    END runQuery;
    Rewriting the query 5 different ways was unfruitful. DB hints were also unfruitful in this particular case. LargeTable.pk_id was an indexed field as were all other join fields.
    Solution:
    Lacking other options, I wrote a literal query that concatenated the variable args. Open a cursor for the literal query.
    Upside: It changed the explain plan to the only really fast option and performed at 1 second instead of 10mins.
    Downside: Query not cached for future use. Perfectly fine for this query's purpose.
    Other suggestions are welcome.Best wild guess based on what you've posted is a bind variable mismatch (your column is declared as a NUMBER data type and your bind variable is declared as a VARCHAR for example). Unless you have histograms on the columns in question ... which, if you're using bind variables is usually a really bad idea.
    A basic illustration of my guess
    http://blogs.oracle.com/optimizer/entry/how_do_i_get_sql_executed_from_an_application_to_uses_the_same_execution_plan_i_get_from_sqlplus

  • 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.

  • Oracle not using its own explain plan

    When I run a simple select query on an indexed column on a large (30 million records) table oracle creates a plan using the indexed column and at a cost of 4. However, what it actually does is do a table scan (I can see this in the 'Long Operations' tab in OEM).
    The funny thing is that I have the same query in a ADO application and when the query is run from there, the same plan is created but no table scan is done - and the query returns in less than a second. However, with the table scan it is over a minute.
    When run through SQL plus Oracle creates a plan including the table scan at a cost of 19030.
    In another (dot net) application I used the: "Alter session set optimizer_index_caching=100" and "Alter session set optimizer_index_cost_adj=10" to try to force the optimizer to use the index. It creates the expected plan, but still does the table scan.
    The query is in the form of:
    "Select * from tab where indexedcol = something"
    Im using Oracle 9i 9.2.0.1.0
    Any ideas as I'm completely at a loss?

    Hello
    It sounds to me like this has something to do with bind variable peeking which was introduced in 9i. If the predicate is
    indexedcolumn = :bind_variablethe first time the query is parsed by oracle, it will "peek" at the value in the bind variable and see what it is and will generate an execution plan based on this. That same plan will be used for matching SQL.
    If you use a litteral, it will generate the plan based on that, and will generate a separate plan for each litteral you use (depending on the value of the cursor_sharing initialisation parameter).
    This can cause there to be a difference between the execution plan seen when issuing EXPLAIN PLAN FOR, and the actual exectuion plan used when the query is run.
    Have a look at the following example:
    tylerd@DEV2> CREATE TABLE dt_test_bvpeek(id number, col1 number)
      2  /
    Table created.
    Elapsed: 00:00:00.14
    tylerd@DEV2> INSERT
      2  INTO
      3      dt_test_bvpeek
      4  SELECT
      5      rownum,
      6      CASE
      7          WHEN MOD(rownum, 5) IN (0,1,2,3) THEN
      8              1
      9          ELSE
    10              MOD(rownum, 5)
    11          END
    12      END
    13  FROM
    14      dual
    15  CONNECT BY
    16      LEVEL <= 100000
    17  /
    100000 rows created.
    Elapsed: 00:00:00.81
    tylerd@DEV2> select count(*), col1 from dt_test_bvpeek group by col1
      2  /
      COUNT(*)       COL1
         80000          1
         20000          4
    2 rows selected.
    Elapsed: 00:00:00.09
    tylerd@DEV2> CREATE INDEX dt_test_bvpeek_i1 ON dt_test_bvpeek(col1)
      2  /
    Index created.
    Elapsed: 00:00:00.40
    tylerd@DEV2> EXEC dbms_stats.gather_table_stats( ownname=>USER,-
    tabname=>'DT_TEST_BVPEEK',-
    method_opt=>'FOR ALL INDEXED COLUMNS SIZE 254',-
    cascade=>TRUE -
    );PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.73
    tylerd@DEV2> EXPLAIN PLAN FOR
      2  SELECT
      3      *
      4  FROM
      5      dt_test_bvpeek
      6  WHERE
      7      col1 = 1
      8  /
    Explained.
    Elapsed: 00:00:00.01
    tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
      2  /
    PLAN_TABLE_OUTPUT
    Plan hash value: 2611346395
    | Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |                | 78728 |   538K|    82  (52)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| DT_TEST_BVPEEK | 78728 |   538K|    82  (52)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("COL1"=1)
    13 rows selected.
    Elapsed: 00:00:00.06The execution plan for col1=1 was chosen because oracle was able to see that based on the statistics, col1=1 would result in most of the rows from the table being returned.
    tylerd@DEV2> EXPLAIN PLAN FOR
      2  SELECT
      3      *
      4  FROM
      5      dt_test_bvpeek
      6  WHERE
      7      col1 = 4
      8  /
    Explained.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
      2  /
    PLAN_TABLE_OUTPUT
    Plan hash value: 3223879139
    | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT            |                   | 21027 |   143K|    74  (21)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| DT_TEST_BVPEEK    | 21027 |   143K|    74  (21)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | DT_TEST_BVPEEK_I1 | 21077 |       |    29  (28)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("COL1"=4)
    14 rows selected.
    Elapsed: 00:00:00.04This time, the optimiser was able to see that col1=4 would result in far fewer rows so it chose to use an index. Look what happens however when we use a bind variable with EXPLAIN PLAN FOR - especially the number of rows the optimiser estimates to be returned from the table
    tylerd@DEV2> var an_col1 NUMBER
    tylerd@DEV2> exec :an_col1:=1;
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.00
    tylerd@DEV2>
    tylerd@DEV2> EXPLAIN PLAN FOR
      2  SELECT
      3      *
      4  FROM
      5      dt_test_bvpeek
      6  WHERE
      7      col1 = :an_col1
      8  /
    Explained.
    Elapsed: 00:00:00.01
    tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
      2  /
    PLAN_TABLE_OUTPUT
    Plan hash value: 2611346395
    | Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |                | 49882 |   340K|   100  (60)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| DT_TEST_BVPEEK | 49882 |   340K|   100  (60)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("COL1"=TO_NUMBER(:AN_COL1))
    13 rows selected.
    Elapsed: 00:00:00.04
    tylerd@DEV2>
    tylerd@DEV2> exec :an_col1:=4;
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.01
    tylerd@DEV2>
    tylerd@DEV2> EXPLAIN PLAN FOR
      2  SELECT
      3      *
      4  FROM
      5      dt_test_bvpeek
      6  WHERE
      7      col1 = :an_col1
      8  /
    Explained.
    Elapsed: 00:00:00.01
    tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
      2  /
    PLAN_TABLE_OUTPUT
    Plan hash value: 2611346395
    | Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |                | 49882 |   340K|   100  (60)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| DT_TEST_BVPEEK | 49882 |   340K|   100  (60)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("COL1"=TO_NUMBER(:AN_COL1))
    13 rows selected.
    Elapsed: 00:00:00.07For both values of the bind variable, the optimiser has no idea what the value will be so it has to make a calculation based on a formula which results in it estimating that the query will return roughly half of the rows in the table, and so it chooses a full scan.
    Now when we actually run the query, the optimiser can take advantage of bind variable peeking and have a look at the value the first time round and base the execution plan on that:
    tylerd@DEV2> exec :an_col1:=1;
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT
      2      *
      3  FROM
      4      dt_test_bvpeek
      5  WHERE
      6      col1 = :an_col1
      7  /
    80000 rows selected.
    Elapsed: 00:00:10.98
    tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
      2  /
    PREV_SQL_ID
    9t52uyyq67211
    1 row selected.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT
      2      operation,
      3      options,
      4      object_name
      5  FROM
      6      v$sql_plan
      7  WHERE
      8      sql_id = '9t52uyyq67211'
      9  /
    OPERATION                      OPTIONS                        OBJECT_NAME
    SELECT STATEMENT
    TABLE ACCESS                   FULL                           DT_TEST_BVPEEK
    2 rows selected.
    Elapsed: 00:00:00.03It saw that the bind variable value was 1 and that this would return most of the rows in the table so it chose a full scan.
    tylerd@DEV2> exec :an_col1:=4
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT
      2      *
      3  FROM
      4      dt_test_bvpeek
      5  WHERE
      6      col1 = :an_col1
      7  /
    20000 rows selected.
    Elapsed: 00:00:03.50
    tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
      2  /
    PREV_SQL_ID
    9t52uyyq67211
    1 row selected.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT
      2      operation,
      3      options,
      4      object_name
      5  FROM
      6      v$sql_plan
      7  WHERE
      8      sql_id = '9t52uyyq67211'
      9  /
    OPERATION                      OPTIONS                        OBJECT_NAME
    SELECT STATEMENT
    TABLE ACCESS                   FULL                           DT_TEST_BVPEEK
    2 rows selected.
    Elapsed: 00:00:00.01Even though the value of the bind variable changed, the optimiser saw that it already had a cached version of the sql statement along with an execution plan, so it used that rather than regenerating the plan. We can check the reverse of this by causing the statement to be invalidated and re-parsed - there's lots of ways, but I'm just going to rename the table:
    Elapsed: 00:00:00.03
    tylerd@DEV2> alter table dt_test_bvpeek rename to dt_test_bvpeek1
      2  /
    Table altered.
    Elapsed: 00:00:00.01
    tylerd@DEV2>
    20000 rows selected.
    Elapsed: 00:00:04.81
    tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
      2  /
    PREV_SQL_ID
    6ztnn4fyt6y5h
    1 row selected.
    Elapsed: 00:00:00.00
    tylerd@DEV2> SELECT
      2      operation,
      3      options,
      4      object_name
      5  FROM
      6      v$sql_plan
      7  WHERE
      8      sql_id = '6ztnn4fyt6y5h'
      9  /
    OPERATION                      OPTIONS                        OBJECT_NAME
    SELECT STATEMENT
    TABLE ACCESS                   BY INDEX ROWID                 DT_TEST_BVPEEK1
    INDEX                          RANGE SCAN                     DT_TEST_BVPEEK_I1
    3 rows selected.
    80000 rows selected.
    Elapsed: 00:00:10.61
    tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
      2  /
    PREV_SQL_ID
    6ztnn4fyt6y5h
    1 row selected.
    Elapsed: 00:00:00.01
    tylerd@DEV2> SELECT
      2      operation,
      3      options,
      4      object_name
      5  FROM
      6      v$sql_plan
      7  WHERE
      8      sql_id = '6ztnn4fyt6y5h'
      9  /
    OPERATION                      OPTIONS                        OBJECT_NAME
    SELECT STATEMENT
    TABLE ACCESS                   BY INDEX ROWID                 DT_TEST_BVPEEK1
    INDEX                          RANGE SCAN                     DT_TEST_BVPEEK_I1
    3 rows selected.This time round, the optimiser peeked at the bind variable the first time the statement was exectued and found it to be 4, so it based the execution plan on that and chose an index range scan. When the statement was executed again, it used the plan it had already executed.
    HTH
    David

  • DECODE is changing the explain plan

    I have a statement with a decode function in the where clause like this:
    AND decode(:cropcode,-1,'-1',sdu.u_crop_group) = decode(:cropcode,-1,'-1',:cropcode)When I a pass -1 as parameter for cropgroup the filter would result in "AND '-1' = '-1' and the statement is executed in less than 2 seconds. When I leave out this where clause it takes almost 18 seconds. The result is the same so I don't understand why the explain plan is so much different and why not using index scans in the statement without decode.
    Below the explain plans and tkprofs for 1 (without decode) and 2 (with decode).
    *explain 1*
    {code}
    SQL Statement which produced this data:
    select * from table(dbms_xplan.display)
    PLAN_TABLE_OUTPUT
    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)|
    | 0 | SELECT STATEMENT | | 7080 | 2413K| | 43611 (2)|
    | 1 | SORT ORDER BY | | 7080 | 2413K| 5224K| 43611 (2)|
    |* 2 | FILTER | | | | | |
    |* 3 | HASH JOIN | | 7156 | 2438K| | 43075 (2)|
    | 4 | TABLE ACCESS FULL | DWH_ABS_DETERMINATION | 17745 | 363K| | 83 (0)|
    |* 5 | HASH JOIN OUTER | | 7156 | 2292K| | 42991 (2)|
    |* 6 | HASH JOIN | | 7156 | 1355K| | 42907 (2)|
    |* 7 | HASH JOIN | | 6987 | 1187K| | 19170 (2)|
    |* 8 | HASH JOIN | | 6947 | 963K| | 10376 (1)|
    |* 9 | TABLE ACCESS BY INDEX ROWID | ALIQUOT | 3 | 144 | | 3 (0)|
    | 10 | NESTED LOOPS | | 6907 | 897K| | 8577 (1)|
    |* 11 | HASH JOIN | | 2264 | 187K| | 1782 (2)|
    | 12 | TABLE ACCESS BY INDEX ROWID | SAMPLE | 190 | 4370 | | 17 (0)|
    | 13 | NESTED LOOPS | | 2264 | 152K| | 107 (1)|
    | 14 | NESTED LOOPS | | 12 | 552 | | 25 (0)|
    |* 15 | TABLE ACCESS FULL | SDG_USER | 12 | 288 | | 13 (0)|
    | 16 | TABLE ACCESS BY INDEX ROWID| SDG | 1 | 22 | | 1 (0)|
    |* 17 | INDEX UNIQUE SCAN | PK_SDG | 1 | | | 0 (0)|
    |* 18 | INDEX RANGE SCAN | FK_SAMPLE_SDG | 597 | | | 2 (0)|
    | 19 | TABLE ACCESS FULL | SAMPLE_USER | 1078K| 16M| | 1669 (1)|
    |* 20 | INDEX RANGE SCAN | FK_ALIQUOT_SAMPLE | 3 | | | 2 (0)|
    | 21 | TABLE ACCESS FULL | ALIQUOT_USER | 3403K| 29M| | 1781 (3)|
    | 22 | TABLE ACCESS FULL | TEST | 3423K| 104M| | 8775 (2)|
    |* 23 | TABLE ACCESS FULL | RESULT | 3435K| 65M| | 23718 (2)|
    | 24 | VIEW | PLATE | 21787 | 2851K| | 84 (2)|
    |* 25 | FILTER | | | | | |
    | 26 | TABLE ACCESS FULL | PLATE | 21787 | 574K| | 84 (2)|
    |* 27 | INDEX UNIQUE SCAN | PK_OPERATOR_GROUP | 1 | 7 | | 0 (0)|
    |* 28 | INDEX UNIQUE SCAN | PK_OPERATOR_GROUP | 1 | 7 | | 0 (0)|
    |* 29 | INDEX UNIQUE SCAN | PK_OPERATOR_GROUP | 1 | 7 | | 0 (0)|
    |* 30 | INDEX UNIQUE SCAN | PK_OPERATOR_GROUP | 1 | 7 | | 0 (0)|
    |* 31 | INDEX UNIQUE SCAN | PK_OPERATOR_GROUP | 1 | 7 | | 0 (0)|
    Predicate Information (identified by operation id):
    2 - filter(("GROUP_ID" IS NULL OR EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP"
    "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B1)) AND ("GROUP_ID" IS NULL
    OR EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP" "OPERATOR_GROUP" WHERE
    "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B2)) AND ("GROUP_ID" IS NULL OR EXISTS (SELECT /*+
    */ 0 FROM "LIMS"."OPERATOR_GROUP" "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND
    "GROUP_ID"=:B3)) AND ("GROUP_ID" IS NULL OR EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP"
    "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B4)))
    3 - access("U_ABS_DETERMINATION"="DETERMINATION_ASSIGNMENT")
    5 - access("PLT"."PLATE_ID"(+)="PLATE_ID")
    6 - access("TEST_ID"="TEST_ID")
    7 - access("ALIQUOT_ID"="ALIQUOT_ID")
    8 - access("ALIQUOT_ID"="ALIQUOT_ID")
    9 - filter("STATUS"='C' OR "STATUS"='P' OR "STATUS"='V')
    11 - access("SAMPLE_ID"="SAMPLE_ID")
    15 - filter("U_ABS_DETERMINATION" IS NOT NULL AND "U_CLIENT_TYPE"='QC' AND
    "U_WEEK_OF_PROCESSING"=TO_NUMBER(:WEEK) AND "U_YEAR_OF_SAMPLE_DELIVERY"=TO_NUMBER(:YEAR))
    17 - access("SDG_ID"="SDG_ID")
    18 - access("SDG_ID"="SDG_ID")
    20 - access("SAMPLE_ID"="SAMPLE_ID")
    23 - filter("NAME"='End result')
    25 - filter("GROUP_ID" IS NULL OR EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP"
    "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B1))
    27 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    28 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    29 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    30 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    31 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    Note
    - 'PLAN_TABLE' is old version
    {code}
    *tkprof 1*
    {code}
    TKPROF: Release 10.2.0.3.0 - Production on Tue Jan 13 13:21:47 2009
    Copyright (c) 1982, 2005, Oracle. All rights reserved.
    Trace file: C:\oracle\product\10.2.0\admin\nautp02\udump\nautp02_ora_880.trc
    Sort options: default
    count = number of times OCI procedure was executed
    cpu = cpu time in seconds executing
    elapsed = elapsed time in seconds executing
    disk = number of physical reads of buffers from disk
    query = number of buffers gotten for consistent read
    current = number of buffers gotten in current mode (usually for update)
    rows = number of rows processed by the fetch or execute call
    SELECT sdu.u_crop_group,
    sd.name as sdg_name,
    ad.variety_name,
    ad.batch_number,
    a.name as aliquot_name,
    sau.u_box_code as box_code,
    sau.u_box_position as box_position,
    t.name as test_name,
    r.original_result,
    plt.name as plate_name,
    concat(chr(a.plate_row + 64),a.plate_column) as plate_position,
    au.u_replicate_number as replicate_number
    FROM lims_sys.sdg sd,
    lims_sys.sdg_user sdu,
    lims_sys.sample sa,
    lims_sys.sample_user sau,
    lims_sys.aliquot a,
    lims_sys.aliquot_user au,
    lims_sys.test t,
    lims_sys.result r,
    lims_sys.plate plt,
    lims_sys.abs_determination ad
    WHERE sd.sdg_id = sdu.sdg_id
    AND sd.sdg_id = sa.sdg_id
    AND sa.sample_id = sau.sample_id
    AND sau.sample_id = a.sample_id
    AND a.aliquot_id = au.aliquot_id
    AND au.aliquot_id = t.aliquot_id
    AND t.test_id = r.test_id
    AND plt.plate_id (+) = a.plate_id
    AND sdu.u_abs_determination = ad.determination_assignment
    AND a.status IN ('V','P','C')
    AND r.name = 'End result'
    AND sdu.u_client_type = 'QC'
    AND sdu.u_year_of_sample_delivery = (:year)
    AND sdu.u_week_of_processing = (:week)
    --AND decode(:cropcode,-1,'-1',sdu.u_crop_group) = decode(:cropcode,-1,'-1',:cropcode)
    ORDER BY box_code, box_position, replicate_number
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 1.15 1.16 0 0 0 0
    Fetch 1 8.53 16.10 227649 241266 0 500
    total 3 9.68 17.27 227649 241266 0 500
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 97
    Rows Row Source Operation
    500 SORT ORDER BY (cr=241266 pr=227649 pw=0 time=16104631 us)
    21311 FILTER (cr=241266 pr=227649 pw=0 time=16246749 us)
    21311 HASH JOIN (cr=241266 pr=227649 pw=0 time=16225434 us)
    17745 TABLE ACCESS FULL DWH_ABS_DETERMINATION (cr=374 pr=0 pw=0 time=69 us)
    21311 HASH JOIN RIGHT OUTER (cr=240892 pr=227649 pw=0 time=16170607 us)
    21895 VIEW PLATE (cr=316 pr=0 pw=0 time=43825 us)
    21895 FILTER (cr=316 pr=0 pw=0 time=43823 us)
    21895 TABLE ACCESS FULL PLATE (cr=316 pr=0 pw=0 time=31 us)
    0 INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    21311 HASH JOIN (cr=240576 pr=227649 pw=0 time=16106174 us)
    21311 HASH JOIN (cr=133559 pr=121596 pw=0 time=9594130 us)
    21311 HASH JOIN (cr=94323 pr=83281 pw=0 time=6917067 us)
    21311 HASH JOIN (cr=86383 pr=75547 pw=0 time=5509672 us)
    7776 HASH JOIN (cr=8134 pr=0 pw=0 time=285364 us)
    7776 TABLE ACCESS BY INDEX ROWID SAMPLE (cr=572 pr=0 pw=0 time=27152 us)
    7876 NESTED LOOPS (cr=377 pr=0 pw=0 time=488287 us)
    99 HASH JOIN (cr=160 pr=0 pw=0 time=4168 us)
    99 TABLE ACCESS FULL SDG_USER (cr=53 pr=0 pw=0 time=1209 us)
    5719 TABLE ACCESS FULL SDG (cr=107 pr=0 pw=0 time=17 us)
    7776 INDEX RANGE SCAN FK_SAMPLE_SDG (cr=217 pr=0 pw=0 time=623 us)(object id 45990)
    1079741 TABLE ACCESS FULL SAMPLE_USER (cr=7562 pr=0 pw=0 time=24 us)
    3307948 TABLE ACCESS FULL ALIQUOT (cr=78249 pr=75547 pw=0 time=3331129 us)
    3406836 TABLE ACCESS FULL ALIQUOT_USER (cr=7940 pr=7734 pw=0 time=556 us)
    3406832 TABLE ACCESS FULL TEST (cr=39236 pr=38315 pw=0 time=3413192 us)
    3406832 TABLE ACCESS FULL RESULT (cr=107017 pr=106053 pw=0 time=6848487 us)
    0 INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    0 INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    0 INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    0 INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    select 'x'
    from
    dual
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 0.00 0.00 0 0 0 0
    Fetch 1 0.00 0.00 0 0 0 1
    total 3 0.00 0.00 0 0 0 1
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 97
    Rows Row Source Operation
    1 FAST DUAL (cr=0 pr=0 pw=0 time=3 us)
    begin :id := sys.dbms_transaction.local_transaction_id; end;
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 0.00 0.00 0 0 0 1
    Fetch 0 0.00 0.00 0 0 0 0
    total 2 0.00 0.00 0 0 0 1
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 97
    OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
    call count cpu elapsed disk query current rows
    Parse 3 0.00 0.00 0 0 0 0
    Execute 3 1.15 1.16 0 0 0 1
    Fetch 2 8.53 16.10 227649 241266 0 501
    total 8 9.68 17.27 227649 241266 0 502
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
    call count cpu elapsed disk query current rows
    Parse 30 0.00 0.00 0 0 0 0
    Execute 30 0.00 0.00 0 0 0 0
    Fetch 30 0.00 0.00 0 40 0 10
    total 90 0.00 0.00 0 40 0 10
    Misses in library cache during parse: 0
    3 user SQL statements in session.
    30 internal SQL statements in session.
    33 SQL statements in session.
    Trace file: C:\oracle\product\10.2.0\admin\nautp02\udump\nautp02_ora_880.trc
    Trace file compatibility: 10.01.00
    Sort options: default
    8 sessions in tracefile.
    3 user SQL statements in trace file.
    30 internal SQL statements in trace file.
    33 SQL statements in trace file.
    6 unique SQL statements in trace file.
    633 lines in trace file.
    23 elapsed seconds in trace file.
    {code}

    explain 2
    SQL Statement which produced this data:
      select * from table(dbms_xplan.display)
    PLAN_TABLE_OUTPUT
    | Id  | Operation                               | Name                     | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                        |                          |    71 | 24779 |   857   (1)|
    |   1 |  SORT ORDER BY                          |                          |    71 | 24779 |   857   (1)|
    |*  2 |   FILTER                                |                          |       |       |            |
    |*  3 |    TABLE ACCESS BY INDEX ROWID          | RESULT                   |     1 |    20 |     4   (0)|
    |   4 |     NESTED LOOPS                        |                          |    72 | 25128 |   856   (1)|
    |   5 |      NESTED LOOPS                       |                          |    70 | 23030 |   576   (1)|
    |*  6 |       HASH JOIN OUTER                   |                          |    69 | 20493 |   369   (1)|
    |   7 |        NESTED LOOPS                     |                          |    69 | 11247 |   285   (0)|
    |   8 |         NESTED LOOPS                    |                          |    69 | 10626 |   147   (0)|
    |   9 |          NESTED LOOPS                   |                          |    23 |  2438 |    78   (0)|
    |  10 |           NESTED LOOPS                  |                          |    23 |  2070 |    32   (0)|
    |  11 |            NESTED LOOPS                 |                          |     1 |    67 |    15   (0)|
    |  12 |             NESTED LOOPS                |                          |     1 |    45 |    14   (0)|
    |* 13 |              TABLE ACCESS FULL          | SDG_USER                 |     1 |    24 |    13   (0)|
    |  14 |              TABLE ACCESS BY INDEX ROWID| DWH_ABS_DETERMINATION    |     1 |    21 |     1   (0)|
    |* 15 |               INDEX UNIQUE SCAN         | PK_DWH_ABS_DETERMINATION |     1 |       |     0   (0)|
    |  16 |             TABLE ACCESS BY INDEX ROWID | SDG                      |     1 |    22 |     1   (0)|
    |* 17 |              INDEX UNIQUE SCAN          | PK_SDG                   |     1 |       |     0   (0)|
    |  18 |            TABLE ACCESS BY INDEX ROWID  | SAMPLE                   |   190 |  4370 |    17   (0)|
    |* 19 |             INDEX RANGE SCAN            | FK_SAMPLE_SDG            |   597 |       |     2   (0)|
    |  20 |           TABLE ACCESS BY INDEX ROWID   | SAMPLE_USER              |     1 |    16 |     2   (0)|
    |* 21 |            INDEX UNIQUE SCAN            | PK_SAMPLE_USER           |     1 |       |     1   (0)|
    |* 22 |          TABLE ACCESS BY INDEX ROWID    | ALIQUOT                  |     3 |   144 |     3   (0)|
    |* 23 |           INDEX RANGE SCAN              | FK_ALIQUOT_SAMPLE        |     3 |       |     2   (0)|
    |  24 |         TABLE ACCESS BY INDEX ROWID     | ALIQUOT_USER             |     1 |     9 |     2   (0)|
    |* 25 |          INDEX UNIQUE SCAN              | PK_ALIQUOT_USER          |     1 |       |     1   (0)|
    |  26 |        VIEW                             | PLATE                    | 21787 |  2851K|    84   (2)|
    |* 27 |         FILTER                          |                          |       |       |            |
    |  28 |          TABLE ACCESS FULL              | PLATE                    | 21787 |   574K|    84   (2)|
    |* 29 |          INDEX UNIQUE SCAN              | PK_OPERATOR_GROUP        |     1 |     7 |     0   (0)|
    |  30 |       TABLE ACCESS BY INDEX ROWID       | TEST                     |     1 |    32 |     3   (0)|
    |* 31 |        INDEX RANGE SCAN                 | FK_TEST_ALIQUOT          |     1 |       |     2   (0)|
    |* 32 |      INDEX RANGE SCAN                   | FK_RESULT_TEST           |     2 |       |     2   (0)|
    |* 33 |    INDEX UNIQUE SCAN                    | PK_OPERATOR_GROUP        |     1 |     7 |     0   (0)|
    |* 34 |    INDEX UNIQUE SCAN                    | PK_OPERATOR_GROUP        |     1 |     7 |     0   (0)|
    |* 35 |    INDEX UNIQUE SCAN                    | PK_OPERATOR_GROUP        |     1 |     7 |     0   (0)|
    |* 36 |    INDEX UNIQUE SCAN                    | PK_OPERATOR_GROUP        |     1 |     7 |     0   (0)|
    Predicate Information (identified by operation id):
       2 - filter(("GROUP_ID" IS NULL OR  EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP"
                  "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B1)) AND ("GROUP_ID"
                  IS NULL OR  EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP" "OPERATOR_GROUP" WHERE
                  "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B2)) AND ("GROUP_ID" IS NULL OR  EXISTS
                  (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP" "OPERATOR_GROUP" WHERE
                  "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B3)) AND ("GROUP_ID" IS NULL OR  EXISTS
                  (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP" "OPERATOR_GROUP" WHERE
                  "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B4)))
       3 - filter("NAME"='End result')
       6 - access("PLT"."PLATE_ID"(+)="PLATE_ID")
      13 - filter("U_ABS_DETERMINATION" IS NOT NULL AND "U_CLIENT_TYPE"='QC' AND
                  "U_WEEK_OF_PROCESSING"=TO_NUMBER(:WEEK) AND "U_YEAR_OF_SAMPLE_DELIVERY"=TO_NUMBER(:YEAR) AND
                  DECODE(:CROPCODE,(-1),'-1',"U_CROP_GROUP")=DECODE(:CROPCODE,(-1),'-1',:CROPCODE))
      15 - access("U_ABS_DETERMINATION"="DETERMINATION_ASSIGNMENT")
      17 - access("SDG_ID"="SDG_ID")
      19 - access("SDG_ID"="SDG_ID")
      21 - access("SAMPLE_ID"="SAMPLE_ID")
      22 - filter("STATUS"='C' OR "STATUS"='P' OR "STATUS"='V')
      23 - access("SAMPLE_ID"="SAMPLE_ID")
      25 - access("ALIQUOT_ID"="ALIQUOT_ID")
      27 - filter("GROUP_ID" IS NULL OR  EXISTS (SELECT /*+ */ 0 FROM "LIMS"."OPERATOR_GROUP"
                  "OPERATOR_GROUP" WHERE "OPERATOR_ID"="LIMS$OPERATOR_ID"() AND "GROUP_ID"=:B1))
      29 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
      31 - access("ALIQUOT_ID"="ALIQUOT_ID")
      32 - access("TEST_ID"="TEST_ID")
      33 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
      34 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
      35 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
      36 - access("GROUP_ID"=:B1 AND "OPERATOR_ID"="LIMS$OPERATOR_ID"())
    Note
       - 'PLAN_TABLE' is old version
    tkprof 2
    TKPROF: Release 10.2.0.3.0 - Production on Tue Jan 13 13:28:26 2009
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Trace file: C:\oracle\product\10.2.0\admin\nautp02\udump\nautp02_ora_5456.trc
    Sort options: default
    count    = number of times OCI procedure was executed
    cpu      = cpu time in seconds executing
    elapsed  = elapsed time in seconds executing
    disk     = number of physical reads of buffers from disk
    query    = number of buffers gotten for consistent read
    current  = number of buffers gotten in current mode (usually for update)
    rows     = number of rows processed by the fetch or execute call
    SELECT sdu.u_crop_group,
           sd.name as sdg_name,
           ad.variety_name,
           ad.batch_number,
           a.name as aliquot_name,
           sau.u_box_code as box_code,
           sau.u_box_position as box_position,
           t.name as test_name,
           r.original_result,
           plt.name as plate_name,
           concat(chr(a.plate_row + 64),a.plate_column) as plate_position,
           au.u_replicate_number as replicate_number
    FROM lims_sys.sdg sd,
         lims_sys.sdg_user sdu,
         lims_sys.sample sa,
         lims_sys.sample_user sau,
         lims_sys.aliquot a,
         lims_sys.aliquot_user au,
         lims_sys.test t,
         lims_sys.result r,
         lims_sys.plate plt,
         lims_sys.abs_determination ad
    WHERE sd.sdg_id = sdu.sdg_id
      AND sd.sdg_id = sa.sdg_id
      AND sa.sample_id = sau.sample_id
      AND sau.sample_id = a.sample_id
      AND a.aliquot_id = au.aliquot_id
      AND au.aliquot_id = t.aliquot_id
      AND t.test_id = r.test_id
      AND plt.plate_id (+) = a.plate_id
      AND sdu.u_abs_determination = ad.determination_assignment
      AND a.status IN ('V','P','C')
      AND r.name = 'End result'
      AND sdu.u_client_type = 'QC'
      AND sdu.u_year_of_sample_delivery = (:year)
      AND sdu.u_week_of_processing = (:week)
      AND decode(:cropcode,-1,'-1',sdu.u_crop_group) = decode(:cropcode,-1,'-1',:cropcode)
    ORDER BY box_code, box_position, replicate_number
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.01       0.00          0          0          0           0
    Execute      1      0.45       0.87          0          0          0           0
    Fetch        1      1.00       0.99          0     221420          0         500
    total        3      1.46       1.86          0     221420          0         500
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 97 
    Rows     Row Source Operation
        500  SORT ORDER BY (cr=221420 pr=0 pw=0 time=992364 us)
      21311   FILTER  (cr=221420 pr=0 pw=0 time=1128970 us)
      21311    TABLE ACCESS BY INDEX ROWID RESULT (cr=221420 pr=0 pw=0 time=1086345 us)
      42623     NESTED LOOPS  (cr=217549 pr=0 pw=0 time=30006317 us)
      21311      NESTED LOOPS  (cr=174880 pr=0 pw=0 time=809278 us)
      21311       NESTED LOOPS  (cr=110117 pr=0 pw=0 time=553538 us)
      21311        HASH JOIN OUTER (cr=46182 pr=0 pw=0 time=319102 us)
      21311         TABLE ACCESS BY INDEX ROWID ALIQUOT (cr=45866 pr=0 pw=0 time=193037 us)
      29088          NESTED LOOPS  (cr=39885 pr=0 pw=0 time=320084 us)
       7776           NESTED LOOPS  (cr=24267 pr=0 pw=0 time=156721 us)
       7776            NESTED LOOPS  (cr=937 pr=0 pw=0 time=78954 us)
         99             NESTED LOOPS  (cr=454 pr=0 pw=0 time=3826 us)
         99              NESTED LOOPS  (cr=253 pr=0 pw=0 time=2833 us)
         99               TABLE ACCESS FULL SDG_USER (cr=53 pr=0 pw=0 time=1531 us)
         99               TABLE ACCESS BY INDEX ROWID DWH_ABS_DETERMINATION (cr=200 pr=0 pw=0 time=956 us)
         99                INDEX UNIQUE SCAN PK_DWH_ABS_DETERMINATION (cr=101 pr=0 pw=0 time=438 us)(object id 46965)
         99              TABLE ACCESS BY INDEX ROWID SDG (cr=201 pr=0 pw=0 time=707 us)
         99               INDEX UNIQUE SCAN PK_SDG (cr=101 pr=0 pw=0 time=330 us)(object id 46071)
       7776             TABLE ACCESS BY INDEX ROWID SAMPLE (cr=483 pr=0 pw=0 time=16261 us)
       7776              INDEX RANGE SCAN FK_SAMPLE_SDG (cr=217 pr=0 pw=0 time=562 us)(object id 45990)
       7776            TABLE ACCESS BY INDEX ROWID SAMPLE_USER (cr=23330 pr=0 pw=0 time=64710 us)
       7776             INDEX UNIQUE SCAN PK_SAMPLE_USER (cr=15554 pr=0 pw=0 time=33728 us)(object id 46012)
      21311           INDEX RANGE SCAN FK_ALIQUOT_SAMPLE (cr=15618 pr=0 pw=0 time=43423 us)(object id 45346)
      21895         VIEW  PLATE (cr=316 pr=0 pw=0 time=43833 us)
      21895          FILTER  (cr=316 pr=0 pw=0 time=21936 us)
      21895           TABLE ACCESS FULL PLATE (cr=316 pr=0 pw=0 time=37 us)
          0           INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
      21311        TABLE ACCESS BY INDEX ROWID ALIQUOT_USER (cr=63935 pr=0 pw=0 time=182479 us)
      21311         INDEX UNIQUE SCAN PK_ALIQUOT_USER (cr=42624 pr=0 pw=0 time=99160 us)(object id 45386)
      21311       TABLE ACCESS BY INDEX ROWID TEST (cr=64763 pr=0 pw=0 time=219096 us)
      21311        INDEX RANGE SCAN FK_TEST_ALIQUOT (cr=42669 pr=0 pw=0 time=129354 us)(object id 46222)
      21311      INDEX RANGE SCAN FK_RESULT_TEST (cr=42669 pr=0 pw=0 time=125893 us)(object id 45940)
          0    INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
          0    INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
          0    INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
          0    INDEX UNIQUE SCAN PK_OPERATOR_GROUP (cr=0 pr=0 pw=0 time=0 us)(object id 45769)
    select 'x'
    from
    dual
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch        1      0.00       0.00          0          0          0           1
    total        3      0.00       0.00          0          0          0           1
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 97 
    Rows     Row Source Operation
          1  FAST DUAL  (cr=0 pr=0 pw=0 time=6 us)
    begin :id := sys.dbms_transaction.local_transaction_id; end;
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          2           0
    Execute      1      0.00       0.00          0          0          0           1
    Fetch        0      0.00       0.00          0          0          0           0
    total        2      0.00       0.00          0          0          2           1
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 97 
    OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        3      0.01       0.00          0          0          2           0
    Execute      3      0.45       0.87          0          0          0           1
    Fetch        2      1.00       0.99          0     221420          0         501
    total        8      1.46       1.87          0     221420          2         502
    Misses in library cache during parse: 2
    Misses in library cache during execute: 2
    OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse       43      0.01       0.00          0          0         12           0
    Execute    128      0.00       0.01          0          0          0           0
    Fetch      178      0.00       0.00          0        383          0         465
    total      349      0.01       0.02          0        383         12         465
    Misses in library cache during parse: 5
    Misses in library cache during execute: 5
        3  user  SQL statements in session.
      128  internal SQL statements in session.
      131  SQL statements in session.
    Trace file: C:\oracle\product\10.2.0\admin\nautp02\udump\nautp02_ora_5456.trc
    Trace file compatibility: 10.01.00
    Sort options: default
           1  session in tracefile.
           3  user  SQL statements in trace file.
         128  internal SQL statements in trace file.
         131  SQL statements in trace file.
          19  unique SQL statements in trace file.
        1352  lines in trace file.
         287  elapsed seconds in trace file.

  • Explain plan shows 300T of TempSpc and 999 hours - tuning request

    Hi,
    I have a query which obtains summary statistics. There is an items table which contains the dictionary of items which can be recorded. There is an events table which contains the item ID, timestamp and a value. The query summarizes the data for each item. e.g. Mean, stddev, sample values, length. I have trimmed the query down as simply as possible and am having a problem with large temp space and runtime estimates in the explain plan. Here is the query:
    WITH ChartItems AS (
        SELECT
          ci.itemid,
          ci.label,
          ci.category,
          ci.description,
          COUNT(*),
          COUNT(distinct subject_id)
        FROM mimic2v26.d_chartitems ci
        JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
        --WHERE ci.itemid = 51
        GROUP BY ci.itemid,
                 ci.label,
                 ci.category,
                 ci.description
    --select * from ChartItems;
    , RawData AS (
        SELECT DISTINCT
          ci.itemid,
          ci.label,
          ci.category,
          ci.description,
          last_value(ce.value1) ignore nulls over (partition BY ci.itemid order by
          ce.charttime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS
          value1_last
        FROM ChartItems ci
        JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
    select * from RawData;Which gives this explain plan:
    Plan hash value: 642453121
    | Id  | Operation                    | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |                |  4811G|  1238T|       |  3686M (13)|999:59:59 |
    |   1 |  VIEW                        |                |  4811G|  1238T|       |  3686M (13)|999:59:59 |
    |   2 |   HASH UNIQUE                |                |  4811G|   258T|       |  3686M (13)|999:59:59 |
    |   3 |    WINDOW BUFFER             |                |  4811G|   258T|       |  3686M (13)|999:59:59 |
    |   4 |     SORT GROUP BY            |                |  4811G|   258T|   317T|  3686M (13)|999:59:59 |
    |*  5 |      HASH JOIN               |                |  4811G|   258T|  4943M|    25M (90)| 85:14:28 |
    |   6 |       VIEW                   | VW_DAG_0       |   152M|  3199M|       |  1366K  (1)| 04:33:18 |
    |   7 |        HASH GROUP BY         |                |   152M|  4216M|  5839M|  1366K  (1)| 04:33:18 |
    |*  8 |         HASH JOIN            |                |   152M|  4216M|       |   147K  (2)| 00:29:36 |
    |   9 |          TABLE ACCESS FULL   | D_CHARTITEMS   |  4832 | 96640 |       |     7   (0)| 00:00:01 |
    |  10 |          INDEX FAST FULL SCAN| CHARTEVENTS_O2 |   196M|  1683M|       |   147K  (1)| 00:29:25 |
    |  11 |       TABLE ACCESS FULL      | CHARTEVENTS    |   196M|  6922M|       |   616K  (1)| 02:03:19 |
    Predicate Information (identified by operation id):
       5 - access("CE"."ITEMID"="ITEM_2")300T of temp space! Ouch.
    TKPROF output (I let the query run for a short while. I let it run for ages earlier, but wasn't tracing the session. Should I let it run for longer?):
    TKPROF: Release 11.2.0.3.0 - Development on Tue Jul 10 16:54:27 2012
    Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
    Trace file: /oracle/11gr2/app/oracle/diag/rdbms/mimic2/mimic2/trace/mimic2_ora_6507.trc
    Sort options: default
    count    = number of times OCI procedure was executed
    cpu      = cpu time in seconds executing
    elapsed  = elapsed time in seconds executing
    disk     = number of physical reads of buffers from disk
    query    = number of buffers gotten for consistent read
    current  = number of buffers gotten in current mode (usually for update)
    rows     = number of rows processed by the fetch or execute call
    WITH ChartItems AS (
        SELECT
          ci.itemid,
          ci.label,
          ci.category,
          ci.description,
          COUNT(*),
          COUNT(distinct subject_id)
        FROM mimic2v26.d_chartitems ci
        JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
        GROUP BY ci.itemid,
                 ci.label,
                 ci.category,
                 ci.description
    , RawData AS (
        SELECT DISTINCT
          ci.itemid,                                                                                                                                                                                           
          ci.label,                                                                                                                                                                                            
          ci.category,                                                                                                                                                                                         
          ci.description,                                                                                                                                                                                      
          last_value(ce.value1) ignore nulls over (partition BY ci.itemid order by                                                                                                                             
          ce.charttime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS                                                                                                                            
          value1_last                                                                                                                                                                                          
        FROM ChartItems ci                                                                                                                                                                                     
        JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid                                                                                                                                                 
    select * from RawData                                                                                                                                                                                      
    call     count       cpu    elapsed       disk      query    current        rows                                                                                                                           
    Parse        1      0.02       0.02          0          0          0           0                                                                                                                           
    Execute      1      0.00       0.00          0          0          0           0                                                                                                                           
    Fetch        1    582.40     712.23     705238     737351          0           0                                                                                                                           
    total        3    582.43     712.25     705238     737351          0           0                                                                                                                           
    Misses in library cache during parse: 1                                                                                                                                                                    
    Optimizer mode: ALL_ROWS                                                                                                                                                                                   
    Parsing user id: 85 
    Number of plan statistics captured: 1
    Rows (1st) Rows (avg) Rows (max)  Row Source Operation
             0          0          0  VIEW  (cr=0 pr=0 pw=0 time=184 us cost=3686387254 size=1361581801333882 card=4811243114254)
             0          0          0   HASH UNIQUE (cr=0 pr=0 pw=0 time=180 us cost=3686387254 size=283863343740986 card=4811243114254)
             0          0          0    WINDOW BUFFER (cr=0 pr=0 pw=0 time=74 us cost=3686387254 size=283863343740986 card=4811243114254)
             0          0          0     SORT GROUP BY (cr=0 pr=0 pw=0 time=59 us cost=3686387254 size=283863343740986 card=4811243114254)
    178073889  178073889  178073889      HASH JOIN  (cr=737351 pr=705238 pw=124635 time=476372451 us cost=25572251 size=283863343740986 card=4811243114254)
       6211631    6211631    6211631       VIEW  VW_DAG_0 (cr=613768 pr=581413 pw=35805 time=286546567 us cost=1366486 size=3354399576 card=152472708)
       6211631    6211631    6211631        HASH GROUP BY (cr=613768 pr=581413 pw=35805 time=281271878 us cost=1366486 size=4421708532 card=152472708)
    196182740  196182740  196182740         HASH JOIN  (cr=613768 pr=545608 pw=0 time=557485047 us cost=147987 size=4421708532 card=152472708)
          4832       4832       4832          TABLE ACCESS FULL D_CHARTITEMS (cr=18 pr=16 pw=0 time=13666 us cost=7 size=96640 card=4832)
    196182740  196182740  196182740          INDEX FAST FULL SCAN CHARTEVENTS_O2 (cr=613750 pr=545592 pw=0 time=148428499 us cost=147046 size=1765644660 card=196182740)(object id 96501)
      10683044   10683044   10683044       TABLE ACCESS FULL CHARTEVENTS (cr=123583 pr=123825 pw=0 time=25175510 us cost=616507 size=7258761380 card=196182740)
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                       1        0.00          0.00
      db file sequential read                         2        0.01          0.01
      db file scattered read                          3        0.02          0.03
      direct path read                             5265        0.75         77.13
      asynch descriptor resize                        1        0.00          0.00
      direct path write temp                      15077        0.71         45.54
      direct path read temp                        2387        0.29         13.54
      SQL*Net break/reset to client                   1        0.66          0.66
      SQL*Net message from client                     1        0.00          0.00
    SQL ID: 7jby2dxrpkkm9 Plan Hash: 1388734953
    select SYS_CONTEXT('USERENV','SESSIONID')
    from
    dual
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.01          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch        1      0.00       0.00          0          0          0           1
    total        3      0.00       0.01          0          0          0           1
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 85 
    Number of plan statistics captured: 1
    Rows (1st) Rows (avg) Rows (max)  Row Source Operation
             1          1          1  FAST DUAL  (cr=0 pr=0 pw=0 time=4 us cost=2 size=0 card=1)
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                       1        0.00          0.00
    OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        2      0.02       0.04          0          0          0           0
    Execute      2      0.00       0.00          0          0          0           0
    Fetch        2    582.40     712.23     705238     737351          0           1
    total        6    582.43     712.27     705238     737351          0           1
    Misses in library cache during parse: 2
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                       4        0.00          0.00
      db file sequential read                         2        0.01          0.01
      db file scattered read                          3        0.02          0.03
      direct path read                             5265        0.75         77.13
      asynch descriptor resize                        1        0.00          0.00
      direct path write temp                      15077        0.71         45.54
      direct path read temp                        2387        0.29         13.54
      SQL*Net break/reset to client                   1        0.66          0.66
      SQL*Net message from client                     3       14.99         15.01
    OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        0      0.00       0.00          0          0          0           0
    Execute      0      0.00       0.00          0          0          0           0
    Fetch        0      0.00       0.00          0          0          0           0
    total        0      0.00       0.00          0          0          0           0
    Misses in library cache during parse: 0
        2  user  SQL statements in session.
        0  internal SQL statements in session.
        2  SQL statements in session.
    Trace file: /oracle/11gr2/app/oracle/diag/rdbms/mimic2/mimic2/trace/mimic2_ora_6507.trc
    Trace file compatibility: 11.1.0.7
    Sort options: default
           1  session in tracefile.
           2  user  SQL statements in trace file.
           0  internal SQL statements in trace file.
           2  SQL statements in trace file.
           2  unique SQL statements in trace file.
       24245  lines in trace file.
         728  elapsed seconds in trace file.Optimizer parameters:
    NAME                                               TYPE        VALUE                                                                                               
    optimizer_capture_sql_plan_baselines               boolean     FALSE                                                                                               
    optimizer_dynamic_sampling                         integer     2                                                                                                   
    optimizer_features_enable                          string      11.2.0.3                                                                                            
    optimizer_index_caching                            integer     0                                                                                                   
    optimizer_index_cost_adj                           integer     100                                                                                                 
    optimizer_mode                                     string      ALL_ROWS                                                                                            
    optimizer_secure_view_merging                      boolean     TRUE                                                                                                
    optimizer_use_invisible_indexes                    boolean     FALSE                                                                                               
    optimizer_use_pending_statistics                   boolean     FALSE                                                                                               
    optimizer_use_sql_plan_baselines                   boolean     TRUE                                                                                                 Can anyone help me figure out what's wrong?
    This is a data warehouse, with up to date statistics. The DB is version 11.2.0.3.0
    Thanks,
    Dan

    rp0428 wrote:
    >
    I trimmed the query down to the simplest that I could which still exhibited the problem
    >
    The DISTINCT isn't the issue. The issue is that the query you posted isn't necessary and doesn't appear to be represented in the plan that you posted.
    That makes it hard to tell where the cardinality misestimates are coming from. How many records does the actual first query (the one with the group by) return? You have a SELECT * commented out - how many rows?No, it's not necessary, but then it isn't the full query. The estimates are still wrong when I pass the count columns through to the second query. The full query contains many more analytic functions in the second query, and some additions to the first. It could probably be cleaned up a little, but the current structure makes logical sense. Should I change the aggregates to analytics and move them into the second query? In any case, there definitely seems to be something wrong with the plan.
    I don't know what you mean when you say "doesn't appear to be represented in the plan that you posted".
    I just checked the first query and while the temp space has dropped to a reasonable amount, the number of rows in the hash join is still way off (I didn't notice before because I was looking at the temp space). The rows for d_chartitems and the index on chartevents are correct:
    Plan hash value: 1249235674
    | Id  | Operation               | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT        |                |   152M|    35G|       |  1366K  (1)| 04:33:18 |
    |   1 |  VIEW                   |                |   152M|    35G|       |  1366K  (1)| 04:33:18 |
    |   2 |   WINDOW SORT           |                |   152M|  4216M|  5839M|  1366K  (1)| 04:33:18 |
    |*  3 |    HASH JOIN            |                |   152M|  4216M|       |   147K  (2)| 00:29:36 |
    |   4 |     TABLE ACCESS FULL   | D_CHARTITEMS   |  4832 | 96640 |       |     7   (0)| 00:00:01 |
    |   5 |     INDEX FAST FULL SCAN| CHARTEVENTS_O2 |   196M|  1683M|       |   147K  (1)| 00:29:25 |
    Predicate Information (identified by operation id):
       3 - access("CE"."ITEMID"="CI"."ITEMID")Edited by: danscott on Jul 10, 2012 5:43 PM
    Edited by: danscott on Jul 11, 2012 6:28 AM

  • Explain Plan

    Just Question about Explain Plan.
    Q- 1. Is it Possible to trace a current session query from other session without altering that session. If How can i do it. I can not do it with v$session becuase it will be different sessionid. Also i ndon't want to alter session.
    Q-2 I have SQl statement gives different EXECUTION PLAN on 9R2 and 10g. Is it possible.
    Can any one explain this please

    thank you smoradi and william for your response.
    Sorry for Long Post
    I tried to post it before also. i did not get the conculsion. This are the final results i got. So can any one Help me.
    Following are the information
    I have TKPROF result. can any one expalin me this what it means. Where are wait time.
    I got the explain plan as unnder can any one explain me please i am still having problem solving this
    can any one explain me how to improve the perfomance.
    1.SS_SKU_STORE_WEEk is the biggest table around 12 million rows.
    2. SS_SKU_STORE 50 thosand rows
    3. ITEM 44 thousand
    4.Rest all tables are small.
    SQL>  SELECT   /*+ index( ss_sku_store SS_SKU_ST_PK ) */
      2              TO_NUMBER( ss_sku_store.sku || ss_sku_store.store_num) rowkey,
      3              ss_sku_store.sku psku,
      4              ' ' || INITCAP( item.descrip ) description,
      5              dept_id,
      6              TO_CHAR( dept_id ) || '.' || TO_CHAR( sub_dept_id ) subdepartment,
      7              TO_CHAR( dept_id ) || '.' || TO_CHAR( sub_dept_id ) ||'.'|| TO_CHAR( class_id ) class,
      8              NVL( vendor_id, -1 ),
      9              NVL( buyer_num, -1),
    10              NVL( TRIM(pattern_cd), -1),
    11              DECODE(Color_Cd, 0, -1, NVL( Color_Cd, -1)) Color_Cd,
    12              NVL( size_cd, -1),
    13              -1 list_id,
    14              ss_sku.sku skuattribute,
    15              ss_sku_store.store_num pstore,
    16              INITCAP( store.name ) location,
    17              store.state,
    18              NVL( INITCAP( regional_vp), :cUNASSIGNED) regional_vp,
    19              NVL( INITCAP( regional_merch_mgr), :cUNASSIGNED) regional_merch_mgr,
    20              NVL( INITCAP( district_mgr), :cUNASSIGNED) district_mgr,
    21              NVL( INITCAP( area_mgr), :cUNASSIGNED) area_mgr,
    22              NVL( sq_footage, -1),
    23              SUBSTR( '000' || fashion_attribute.seq, -3, 3 ) || NVL( store.fashion_att_cd, '' ) fashion_att_cd,
    24              SUBSTR( '000' || cust_profile.seq, -3, 3 ) || NVL( store.cust_type_cd, '' ) cust_type_cd,
    25              NVL( section_count, -1) section_count,
    26              '000' corp_vol_grp_cd,
    27              0 storegroup,
    28              store.store_num storeattribute,
    29              0 storesort,
    30              submit_status,
    31              DECODE( current_user, :pUserID, shipment_schedules.check_staged_sku(ss_sku_store.sku,-1), 1) lockedflag,
    32              '' aggregatedrowkey,
    33              '' AttributeDescription,
    34              starting_on_hand     onhand
    35     FROM     cust_profile,
    36              fashion_attribute,
    37              ( SELECT   vendor_id,
    38                         sku
    39                FROM     item_vendor
    40                WHERE    sku IN ( SELECT  sku
    41                                  FROM    ss_session_sku
    42                                  WHERE   user_key = :pUserKey)
    43                AND      primary_flag = :cTRUE ) primaryvendor,
    44              ( SELECT   SKU,
    45                         DECODE( status, 0, 0, DECODE( status, 1 ,0 ,1) ) AS submit_status
    46                FROM     ( SELECT   /*+ full(ss_session_sku) use_nl(ss_session_sku,ss_sku_store_week) index(ss_sku_store_week SS_SKU_STR_WK_SKU )*/
    47                                    SS_SKU_Store_Week.SKU,
    48                                    MAX( NVL( ssk_week_status, 0 ) ) AS status
    49                           FROM     ss_session_sku,
    50                                    ss_sku_store_week
    51                           WHERE    user_key              = :pUserKey
    52                           AND      ss_sku_store_week.sku = ss_session_sku.sku
    53                           GROUP BY ss_sku_store_week.sku )
    54               ) sku_status,
    55              ss_sku,
    56              store,
    57              ss_sku_store,
    58              item
    59     WHERE    sku_status.sku           =  item.sku
    60     AND      sku_status.sku           =  ss_sku.sku
    61     AND      sku_status.sku           =  ss_sku_store.sku
    62     AND      sku_status.sku           =  primaryvendor.sku
    63     AND      sku_status.sku           =  sku_status.sku
    64     AND      ss_sku_store.store_num   =  store.store_num
    65     AND      store.cust_type_cd       =  cust_profile.cust_type_cd(+)
    66     AND      store.fashion_att_cd     =  fashion_attribute.fashion_att_cd(+)
    67     ORDER BY ss_sku_store.sku,
    68              ss_sku_store.store_num;
    Execution Plan
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=531 Card=3203 Bytes=948088)                                                            
       1    0  SORT (GROUP BY) (Cost=531 Card=3203 Bytes=948088)                  
       2    1    HASH JOIN (RIGHT OUTER) (Cost=323 Card=3203 Bytes=948088)                                                                    
       3    2      TABLE ACCESS (FULL) OF 'CUST_PROFILE' (TABLE) (Cost=2 Card=16 Bytes=304)                                                   
       4    2      HASH JOIN (RIGHT OUTER) (Cost=321 Card=3203 Bytes=887231)                                                                  
       5    4        TABLE ACCESS (FULL) OF 'FASHION_ATTRIBUTE' (TABLE) (Cost=2 Card=9 Bytes=162)                                             
       6    4        HASH JOIN (Cost=318 Card=3203 Bytes=829577)                  
       7    6          TABLE ACCESS (FULL) OF 'STORE' (TABLE) (Cost=15 Card=1289 Bytes=105698)                                                
       8    6          TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'SS_SKU_STORE' (TABLE) (Cost=3 Card=707 Bytes=17675)                            
       9    8           NESTED LOOPS (Cost=302 Card=3203 Bytes=566931)           
      10    9             HASH JOIN (Cost=287 Card=5 Bytes=760)                  
      11   10               NESTED LOOPS (Cost=284 Card=5 Bytes=655)             
      12   11                 NESTED LOOPS (Cost=273 Card=5 Bytes=270)           
      13   12                   NESTED LOOPS (Cost=252 Card=86 Bytes=3784)                                                                   
      14   13                     NESTED LOOPS (Cost=17 Card=13 Bytes=468)                                                                   
      15   14                       SORT (UNIQUE) (Cost=1 Card=13 Bytes=130)                                                                 
      16   15                         INDEX (RANGE SCAN) OF 'SS_SESS_SKU_PK' (INDEX (UNIQUE)) (Cost=1 Card=13 Bytes=130)                     
      17   14                       TABLE ACCESS (BY INDEX ROWID) OF 'ITEM_VENDOR' (TABLE) (Cost=3 Card=1 Bytes=26)                          
      18   17                         INDEX (RANGE SCAN) OF 'ITEM_VENDOR_ITEM_FK_IDX' (INDEX) (Cost=2 Card=1)                                
      19   13                     PARTITION HASH (ITERATOR) (Cost=65 Card=7 Bytes=56)                                                        
      20   19                       TABLE ACCESS (BY LOCAL INDEX ROWID)OF 'SS_SKU_STORE_WEEK' (TABLE) (Cost=65 Card=7 Bytes=56)             
      21   20                         INDEX (RANGE SCAN) OF 'SS_SKU_STR_WK_SKU' (INDEX) (Cost=14 Card=6427)                                  
      22   12                   TABLE ACCESS (FULL) OF 'SS_SESSION_SKU'(TABLE) (Cost=0 Card=1 Bytes=10)                                     
      23   11                 TABLE ACCESS (BY INDEX ROWID) OF 'ITEM' (TABLE) (Cost=2 Card=1 Bytes=77)                                       
      24   23                   INDEX (UNIQUE SCAN) OF 'ITEM_PK' (INDEX (UNIQUE)) (Cost=1 Card=1)                                            
      25   10               TABLE ACCESS (FULL) OF 'SS_SKU' (TABLE) (Cost=3 Card=343 Bytes=7203)                                             
      26    9             PARTITION HASH (ITERATOR) (Cost=1 Card=211)
      27   26               INDEX (RANGE SCAN) OF 'SS_SKU_ST_PK' (INDEX(UNIQUE)) (Cost=1 Card=211)                                          
    EXPLIAN PLAN AND DATA FROM TKPROF
    all     count       cpu    elapsed       disk      query    current        rows
    Parse        2      0.00       0.01          0          0          0           0
    Execute      2      1.35       1.30          0          0          0           0
    Fetch        5      0.14       0.16          5       2497          0         111
    total        9      1.49       1.49          5       2497          0         111
    Misses in library cache during parse: 2
    Misses in library cache during execute: 2
    Optimizer mode: ALL_ROWS
    Parsing user id: 30  (MDSEADMIN)
    Rows     Row Source Operation
          0  PX COORDINATOR FORCED SERIAL (cr=797 pr=2 pw=0 time=42745 us)
          0   PX SEND QC (ORDER) :TQ10005 (cr=797 pr=2 pw=0 time=42711 us)
          0    SORT ORDER BY (cr=797 pr=2 pw=0 time=42701 us)
          0     PX RECEIVE  (cr=797 pr=2 pw=0 time=42627 us)
          0      PX SEND RANGE :TQ10004 (cr=797 pr=2 pw=0 time=42617 us)
          0       BUFFER SORT (cr=797 pr=2 pw=0 time=42609 us)
          0        NESTED LOOPS OUTER (cr=797 pr=2 pw=0 time=42532 us)
          0         NESTED LOOPS OUTER (cr=797 pr=2 pw=0 time=42520 us)
          0          NESTED LOOPS  (cr=797 pr=2 pw=0 time=42510 us)
          0           NESTED LOOPS  (cr=797 pr=2 pw=0 time=42502 us)
          0            NESTED LOOPS  (cr=797 pr=2 pw=0 time=42495 us)
          0             NESTED LOOPS  (cr=797 pr=2 pw=0 time=42488 us)
          0              HASH JOIN  (cr=797 pr=2 pw=0 time=42480 us)
          1               BUFFER SORT (cr=5 pr=1 pw=0 time=13357 us)
          1                PX RECEIVE  (cr=5 pr=1 pw=0 time=13300 us)
          1                 PX SEND HASH :TQ10001 (cr=5 pr=1 pw=0 time=13291 us)
          1                  TABLE ACCESS BY INDEX ROWID ITEM_VENDOR (cr=5 pr=1 pw=0 time=13280 us)
          3                   NESTED LOOPS  (cr=4 pr=0 pw=0 time=423 us)
          1                    SORT UNIQUE (cr=1 pr=0 pw=0 time=189 us)
          1                     INDEX RANGE SCAN SS_SESS_SKU_PK (cr=1 pr=0 pw=0 time=86 us)(object id 25279)
          1                    INDEX RANGE SCAN ITEM_VENDOR_ITEM_FK_IDX (cr=3 pr=0 pw=0 time=53 us)(object id 24079)
          0               PX RECEIVE  (cr=792 pr=1 pw=0 time=28530 us)
          0                PX SEND HASH :TQ10003 (cr=792 pr=1 pw=0 time=28524 us)
          0                 VIEW  (cr=792 pr=1 pw=0 time=28517 us)
          0                  HASH GROUP BY (cr=792 pr=1 pw=0 time=28509 us)
          0                   PX RECEIVE  (cr=792 pr=1 pw=0 time=28295 us)
          0                    PX SEND HASH :TQ10002 (cr=792 pr=1 pw=0 time=28290 us)
          0                     NESTED LOOPS  (cr=792 pr=1 pw=0 time=28284 us)
          1                      BUFFER SORT (cr=1 pr=0 pw=0 time=139 us)
          1                       PX RECEIVE  (cr=1 pr=0 pw=0 time=45 us)
          1                        PX SEND BROADCAST :TQ10000 (cr=1 pr=0 pw=0 time=40 us)
          1                         INDEX RANGE SCAN SS_SESS_SKU_PK (cr=1 pr=0 pw=0 time=34 us)(object id 25279)
          0                      PX BLOCK ITERATOR PARTITION: KEY KEY (cr=791 pr=1 pw=0 time=28136 us)
          0                       TABLE ACCESS FULL SS_SKU_STORE_WEEK PARTITION: KEY KEY (cr=791 pr=1 pw=0 time=28084 us)
          0              TABLE ACCESS BY INDEX ROWID ITEM (cr=0 pr=0 pw=0 time=0 us)
          0               INDEX UNIQUE SCAN ITEM_PK (cr=0 pr=0 pw=0 time=0 us)(object id 24055)
          0             TABLE ACCESS BY INDEX ROWID SS_SKU (cr=0 pr=0 pw=0 time=0 us)
          0              INDEX UNIQUE SCAN SS_SKU_PK (cr=0 pr=0 pw=0 time=0 us)(object id 25300)
          0            PARTITION HASH ITERATOR PARTITION: KEY KEY (cr=0 pr=0 pw=0 time=0 us)
          0             TABLE ACCESS BY LOCAL INDEX ROWID SS_SKU_STORE PARTITION: KEY KEY (cr=0 pr=0 pw=0 time=0 us)
          0              INDEX RANGE SCAN SS_SKU_ST_PK PARTITION: KEY KEY (cr=0 pr=0 pw=0 time=0 us)(object id 25547)
          0           TABLE ACCESS BY INDEX ROWID STORE (cr=0 pr=0 pw=0 time=0 us)
          0            INDEX UNIQUE SCAN STORE_PK (cr=0 pr=0 pw=0 time=0 us)(object id 25586)
          0          TABLE ACCESS BY INDEX ROWID FASHION_ATTRIBUTE (cr=0 pr=0 pw=0 time=0 us)
          0           INDEX UNIQUE SCAN FASHION_ATTRIBUTE_PK (cr=0 pr=0 pw=0 time=0 us)(object id 24035)
          0         TABLE ACCESS BY INDEX ROWID CUST_PROFILE (cr=0 pr=0 pw=0 time=0 us)
          0          INDEX UNIQUE SCAN CUST_PROFILE_PK (cr=0 pr=0 pw=0 time=0 us)(object id 24036)
    ALL TOTALS FOR ALL RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse       43      0.10       0.11          0          1          0           0
    Execute    861      0.38       0.45        357        622         46         621
    Fetch      845      0.21       0.21        128       2626          2         892
    total     1749      0.69       0.78        485       3249         48        1513
    Misses in library cache during parse: 21
    Misses in library cache during execute: 16
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                      60        0.00          0.00
      SQL*Net message from client                    39        0.00          0.16
      db file scattered read                         82        0.01          0.05
      db file sequential read                       185        0.01          0.05
      log file sync                                   1        0.00          0.00
      191  user  SQL statements in session.
       23  internal SQL statements in session.
      214  SQL statements in session.
       37  statements EXPLAINed in this session.Thank you for your help in advance
    Message was edited by:
    devmiral

  • Explain Plan vs. V$SQL_PLAN

    Hello everyone,
    I'm trying to understand the difference between those two, I'm relying on the following Tom Kyte article :
    http://tkyte.blogspot.com/2007/04/when-explanation-doesn-sound-quite.html
    In my following example I didn't use TKPROF as he did but AUTOTRACE / V$SQL_PLAN instead (since EXPLAIN PLAN shows a theoretical plan that can be used if this statement were to be executed and V$SQL_PLAN contains the actual plan used)
    That's my code :
    >
    HR> ALTER SYSTEM FLUSH shared_pool ;
    HR>
    HR> create table test
    2 as
    3 select a.*, 1 id
    4 from all_objects a
    5 where rownum = 1;
    Table created.
    HR>
    HR> create index t_idx on test(id);
    Index created.
    HR>
    HR> -- AUTOTRACE vs V$SQL round 1 ...
    HR> ---------------------------------
    HR>
    HR> SET AUTOTRACE ON EXPLAIN
    HR>
    HR> select id, object_name from test where id = 1;
    ID OBJECT_NAME
    1 ICOL$
    Execution Plan
    Plan hash value: 2783519773
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 30 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - access("ID"=1)
    Note
    - dynamic sampling used for this statement (level=2)
    HR>
    HR> SET AUTOTRACE OFF
    HR>
    HR>
    HR> select operation, options, object_name, cost
    2 from v$sql_plan
    3 where hash_value= ( SELECT hash_value
    4 FROM v$sqlarea
    5 WHERE sql_text LIKE 'select id, object_name from test where id = 1'
    6 AND sql_text NOT LIKE '%v_sql%');
    OPERATION OPTIONS OBJECT_NAME COST
    SELECT STATEMENT 2
    TABLE ACCESS BY INDEX ROWID TEST 2
    INDEX RANGE SCAN T_IDX 1
    >
    Ok so in round 1, the optimizer decided to get the 1 row back using Index Range Scan both in "theory" and in "reality", it make sense.
    Now its time for round 2 ... :)
    >
    HR> insert into test select a.*, 1 from all_objects a where rownum < 1001 ;
    1000 rows created.
    HR>
    HR> commit ;
    Commit complete.
    HR>
    HR>
    HR> -- AUTOTRACE vs V$SQL round 2 ...
    HR> ---------------------------------
    HR>
    HR> SET AUTOTRACE ON EXPLAIN
    HR>
    HR> select id, object_name from test where id = 1;
    ID OBJECT_NAME
    1 ICOL$
    1 I_VIEWTRCOL1
    1001 rows selected.
    Execution Plan
    Plan hash value: 2783519773
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1001 | 30030 | 6 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1001 | 30030 | 6 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | T_IDX | 1001 | | 5 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - access("ID"=1)
    Note
    - dynamic sampling used for this statement (level=2)
    HR>
    HR> select operation, options, object_name, cost
    2 from v$sql_plan
    3 where hash_value= ( SELECT hash_value
    4 FROM v$sqlarea
    5 WHERE sql_text LIKE 'select id, object_name from test where id = 1'
    6 AND sql_text NOT LIKE '%v_sql%');
    OPERATION OPTIONS OBJECT_NAME COST
    SELECT STATEMENT 2
    TABLE ACCESS BY INDEX ROWID TEST 2
    INDEX RANGE SCAN T_IDX 1
    HR>
    >
    since explain plan is using always Hard Parse (and it used dynamic sampling) I would expect to see FTS in "theory"
    can anyone explain me why in round 2 they both presented Index Range Scan.
    Thanks ! :)

    Explain plan can lie, autotrace - which just does an explain plan - can lie.
    See:
    http://oracle-randolf.blogspot.com/2012/01/autotrace-polluting-shared-pool.html
    http://kerryosborne.oracle-guy.com/2010/02/autotrace-lies/
    http://hoopercharles.wordpress.com/2010/01/11/explain-plan-lies-autotrace-lies-tkprof-lies-what-is-the-plan/
    V$SQL_PLAN is the truth.
    You didn't mention version but DBMS_XPLAN is the most convenient way to get your plan.
    If the plan is cached, inserting 1000 rows is not going to change the plan.
    SQL> create table test
      2  as
      3  select a.*, 1 id
      4  from all_objects a
      5  where rownum = 1;
    Table created.
    SQL>
    SQL> create index t_idx on test(id);
    Index created.
    SQL>
    SQL> select id, object_name from test where id = 1;
            ID OBJECT_NAME
             1 ORA$BASE
    SQL>
    SQL> select * from table(dbms_xplan.display_cursor);
    PLAN_TABLE_OUTPUT
    SQL_ID  3qan6s0j3uab5, child number 0
    select id, object_name from test where id = 1
    Plan hash value: 2783519773
    | Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT            |       |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST  |     1 |    30 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | T_IDX |     1 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("ID"=1)
    Note
       - dynamic sampling used for this statement (level=4)
    23 rows selected.
    SQL> insert into test select a.*, 1 from all_objects a where rownum < 1001 ;
    1000 rows created.
    SQL> commit;
    Commit complete.
    SQL> select id, object_name from test where id = 1;
    SQL> select * from table(dbms_xplan.display_cursor);
    PLAN_TABLE_OUTPUT
    SQL_ID  3qan6s0j3uab5, child number 0
    select id, object_name from test where id = 1
    Plan hash value: 2783519773
    | Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT            |       |       |       |     2 (100)|          |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST  |     1 |    30 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | T_IDX |     1 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("ID"=1)
    Note
       - dynamic sampling used for this statement (level=4)
    23 rows selected.
    SQL>

  • Cost in explain plan vs elapsed time

    hi gurus,
    i have two tables with identical data volume(same database/schema/tablespace) and the only difference between these two is, one partitioned on a date filed.
    statistics are up to date.
    same query is executed against both tables, no partition pruning involved.
    select ....... from non-partitioned
    execution plan cost=92
    elapsed time=117612
    select ... from partitioned
    execution plan cost=3606
    elapsed time=19559
    though plan cost of query against non-partitioned is quite less than partitioned, elapsed time in v$sqlarea is higher than partitioned.
    what could be the reason please?
    thanks,
    charles
    Edited by: user570138 on May 6, 2010 6:54 AM

    user570138 wrote:
    if elapsed time value is very volatile(with the difference in explain plan cost) , then how can i compare the performance of the query?Note that the same query with same execution plan and same data can provide different execution times - and due to a number of factors. The primary one being that the first time the query is executed, it performs physical I/O and loads the data into the buffer cache - where the same subsequent query finds this data via cheaper and faster logical I/O in the cache.
    in my case i want to compare the performance change before and after table partitioning.Then look at the actual utilisation cost of the query and not (variant) elapsed execution time. The most expensive operation on a db platform is typically I/O. The more I/O, the slower the execution time.
    I/O can be decreased in a number of ways. The usual approach in the database environment is to provide better or alternative data structures, in order to create more optimal I/O paths.
    So instead of using a hash table and separate PK b+tree index, using an index organised table. Instead of a single large table with indexes, a partitioned table with local indexes. Instead of joining plain tables, joining tables that have been clustered. Etc.
    In most cases, when done correctly, these physical data structure changes do not even impact the application layer. The SQL and code in this layer should be blissfully unaware of the physical structure changes done to improve performance.
    Likewise, changes in the logical layer (data model changes) can also improve performance. This of course does impact the application layer - and requires a proper design and implementation in the physical layer. Often proper data modeling is overlooked and flaws in it is attempted to be fixed by hacking the physical layer.
    my aim is to measure the query performance improvements, if any, by partitioning an existing tableWhy not measure current I/O before an operation, and then after the operation - and use the difference to determine the amount of I/O performed by that operation?
    This can be implemented in a start/stop watch fashion (instead of measuring time, measuring I/O) using the v$sesstat virtual performance view.

  • Why tkprof did not show explain plan for some sql statements

    Hi,
    I did a trace for one of the session, hoping to find the explain plan for its tkprof. However, I only get this:
    INSERT INTO AUDIT_TABLE
    VALUES
    ( :B1 , :B2 , :B3 , :B4 , :B5 , :B6 , :B8 , :B7 )
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute   3698      8.08      59.41       3348        566      19092        3698
    Fetch        0      0.00       0.00          0          0          0           0
    total     3699      8.08      59.42       3348        566      19092        3698
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: CHOOSE
    Parsing user id: 30     (recursive depth: 2)
    ********************************************************************************Any idea why the explain plan is missing?
    Also looking at the above statistics, what can I conclude?

    Thanks John. What's ur take on this statistics then?
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        0      0.00       0.00          0          0          0           0
    Execute   1798     12.23      36.75       1758       5404       7418        1798
    Fetch        0      0.00       0.00          0          0          0           0
    total     1798     12.23      36.75       1758       5404       7418        1798
    Misses in library cache during parse: 0
    Optimizer mode: CHOOSE
    Parsing user id: 30     (recursive depth: 1)
    ********************************************************************************

  • 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.

  • Why can the explain plan be different from 2 exact set of structures

    hi,
    i have from a view some base tables let's say A , B, C & D
    this query is running very slow . so from the same database , i created tables A1 , B1, C1,& D1 from the above tables.
    i created some new indexes on A1 to D1 tables and the results returned to me is fast.
    i did an exlain plan
    so i drop the indexes on the original A to D table and created the new indexes as per A1 to D1 and analyzed them. and i also did an explain plan
    but the query is still running slow and also the explain plan is different to the one from A1 to D1 (the one that running fast)
    pls help me to understand how/why can this happen ?
    tks & rdgs

    hi,
    precisely i could have been providing insufficient information but i am too inexperienced to be able to give you the required information and i am also not very sure where i could get the info so that you all can advise me further.
    but this is from the user_tables , the only difference i see is that
    under LOGGING table A to E is 'YES'
    TABLE_NAME     TABLESPACE_NAME     PCT_FREE     LOGGING     BACKED_UP     NUM_ROWS     BLOCKS     CACHE     TABLE_LOCK     PARTITIONED
    A1          OWNER1          10          NO          N     37332          883         N     ENABLED     NO
    B1          OWNER1          10          NO          N     43458          861         N     ENABLED     NO
    C1          OWNER1          10          NO          N     823828          7826         N     ENABLED     NO
    D1          OWNER1          10          NO          N     881176          14646         N     ENABLED     NO
    E1          OWNER1          10          NO          N     18868          223         N     ENABLED     NO
    A          OWNER1          10          YES          N     37040          880         N     ENABLED     NO
    B          OWNER1          10          YES          N     43386          880         N     ENABLED     NO
    C          OWNER1          10          YES          N     823820          7684         N     ENABLED     NO
    D          OWNER1          50          YES          N     880948          26624         N     ENABLED     NO
    E          OWNER1          10          YES          N     18690          244         N     ENABLED     NOtks & rdgs

  • Tuning needed for sql:EXPLAIN PLAN attached

    DB Version:10gR2
    The below sql was running slow, so i took an explain plan
    SQL> explain plan for
      2  SELECT COUNT(1) FROM SHIP_DTL WHERE
      3  SHIP_DTL.PLT_ID = 'AM834'
      4  AND SHIP_DTL.WHSE = '34' AND
      5  SHIP_DTL.STAT_CODE != '845'
      6  ORDER BY SHIP_DTL.LOAD_SEQ ASC;
    Explained.
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    | Id  | Operation                    |  Name             | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT             |                   |     1 |    18 |     5  (20)|
    |   1 |  SORT AGGREGATE              |                   |     1 |    18 |            |
    |*  2 |   TABLE ACCESS BY INDEX ROWID| SHIP_DTL        |   200 |  3600 |     5  (20)|
    |*  3 |    INDEX RANGE SCAN          | SHIP_DTL_IND_4  |   203 |       |     3   (0)|
    Predicate Information (identified by operation id):
    PLAN_TABLE_OUTPUT
       2 - filter("SHIP_DTL"."WHSE"='34' AND "SHIP_DTL"."STAT_CODE"<>845)
       3 - access("SHIP_DTL"."PLT_ID"='AM834')Why is there an INDEX RANGE scan where there is no BETWEEN operator in the query? What are various options(indexes, rewriting query) in tuning this query?

    james_p wrote:
    DB Version:10gR2
    The below sql was running slow, so i took an explain planCheck your plan, the optimizer estimates that the following query:
    select count(*)
    from SHIP_DTL
    where "SHIP_DTL"."PLT_ID"='AM834';only returns 200 records. Is this correct? Please post the result of above query.
    It probably isn't the case, because retrieving 200 records per index range scan and single row random table access shouldn't take long, at maximum a couple of seconds if you need to read each block actually from disk rather than from the cache.
    If the estimate is wrong you need to check the statistics on the table and index that were used by the optimizer to come to that conclusion.
    Are you sure that this plan is the actual plan used at execution time? You can check for the actual plans used to execute by using the DBMS_XPLAN.DISPLAY_CURSOR function in 10g if the SQL is still cached in the Shared Pool. You need to pass the SQL_ID and SQL_CHILD_NUMBER which you can retrieve from V$SESSION while the statement is executing.
    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/

Maybe you are looking for