Interpreting explain plans oracle 11gr2

Hi,
We are using oracle 11.2.0.3 and plan on evaluating a series of explain plans to determine index/partitioning strategy for a large fact table +a ssociarted dimensions in data warehouse.
Whilst we plan on running a selection of these to get actaul times, wish to evalaute many more eplain plans to guage efficiency of data model.
In terms of interpreting we are going on basis of the lower the row count/cpu cost the better the performance should be.
Plan on using autotrace for these as well.
Any downsides to this /shoudl we look out for anything esle with explain plan.
Is autotrace suffciient in this repsect.
Have also found the time in execution plan can often bear no resembalnce to actaul execution plan.
Any other tips on interpreting explain plans woudl eb appreacited.
Whilst I understand the real times will only come thorugh running the queries want to do prep work with explain plans before run them all.
Thanks
Edited by: user5716448 on 02-Mar-2013 08:26

Don't rely on the cost to tell you how efficient a SQL is. It is based on estimates that are not always correct. Its best use is to tell if something has changed when doing SQL variations - it can and does happen that a lower cost version will use more resources as per AUTOTRACE than a higher-cost version of the SQL.
Also make absoutely sure that the tuned SQL returns the same results as the original :)
Using AUTOTRACE was a good decision. It will provide run-time metrics for your SQL as well as automatically generate execution plans. It does not list CPU usage, which is avialable from V$SQL. Lower resources listed by AUTOTRACE should accompany faster run times in general.

Similar Messages

  • Interpreting Explain Plan - Oracle

    Hi Guys,
    Can advise on this.. try searching around the web but can't find explanation.
    What does the Cost and %CPU stands for?
    thanks

    >
    The cost is an estimated value proportional to the expected resource use needed to execute the statement with a particular plan. The optimizer calculates the cost of access paths and join orders based on the estimated computer resources, which includes I/O, CPU, and memory.
    >
    Please read http://download.oracle.com/docs/cd/E11882_01/server.112/e16638/optimops.htm#i82005.

  • Interpret EXPLAIN PLAN TABLE OUTPUT

    Please point me to some document to understand on how to interpret this data, especially " OUTLINE DATA ".
    ORCL > explain plan for select * from hr.employees e, hr.departments d where e.department_id = d.department_id ;
    Explained.
    Elapsed: 00:00:00.11
    ORCL > select plan_table_output  from table (DBMS_XPLAN.DISPLAY(NULL, NULL, 'ADVANCED')) ;
    PLAN_TABLE_OUTPUT
    Plan hash value: 1343509718
    | Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |             |   106 |  9540 |     6  (17)| 00:00:01 |
    |   1 |  MERGE JOIN                  |             |   106 |  9540 |     6  (17)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS |    27 |   567 |     2   (0)| 00:00:01 |
    |   3 |    INDEX FULL SCAN           | DEPT_ID_PK  |    27 |       |     1   (0)| 00:00:01 |
    |*  4 |   SORT JOIN                  |             |   107 |  7383 |     4  (25)| 00:00:01 |
    |   5 |    TABLE ACCESS FULL         | EMPLOYEES   |   107 |  7383 |     3   (0)| 00:00:01 |
    Query Block Name / Object Alias (identified by operation id):
       1 - SEL$1
       2 - SEL$1 / D@SEL$1
       3 - SEL$1 / D@SEL$1
       5 - SEL$1 / E@SEL$1
    Outline Data
      /*+
          BEGIN_OUTLINE_DATA
          USE_MERGE(@"SEL$1" "E"@"SEL$1")
          LEADING(@"SEL$1" "D"@"SEL$1" "E"@"SEL$1")
          FULL(@"SEL$1" "E"@"SEL$1")
          INDEX(@"SEL$1" "D"@"SEL$1" ("DEPARTMENTS"."DEPARTMENT_ID"))
          OUTLINE_LEAF(@"SEL$1")
          ALL_ROWS
          DB_VERSION('11.2.0.1')
          OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
          IGNORE_OPTIM_EMBEDDED_HINTS
          END_OUTLINE_DATA
    Predicate Information (identified by operation id):
       4 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
           filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
    Column Projection Information (identified by operation id):
       1 - (#keys=0) "D"."DEPARTMENT_ID"[NUMBER,22], "E"."DEPARTMENT_ID"[NUMBER,22],
           "D"."LOCATION_ID"[NUMBER,22], "D"."DEPARTMENT_NAME"[VARCHAR2,30],
           "D"."MANAGER_ID"[NUMBER,22], "E"."EMPLOYEE_ID"[NUMBER,22],
           "E"."FIRST_NAME"[VARCHAR2,20], "E"."LAST_NAME"[VARCHAR2,25],
           "E"."EMAIL"[VARCHAR2,25], "E"."PHONE_NUMBER"[VARCHAR2,20], "E"."HIRE_DATE"[DATE,7],
           "E"."JOB_ID"[VARCHAR2,10], "E"."SALARY"[NUMBER,22],
           "E"."COMMISSION_PCT"[NUMBER,22], "E"."MANAGER_ID"[NUMBER,22]
       2 - "D"."DEPARTMENT_ID"[NUMBER,22], "D"."DEPARTMENT_NAME"[VARCHAR2,30],
           "D"."MANAGER_ID"[NUMBER,22], "D"."LOCATION_ID"[NUMBER,22]
       3 - "D".ROWID[ROWID,10], "D"."DEPARTMENT_ID"[NUMBER,22]
       4 - (#keys=1) "E"."DEPARTMENT_ID"[NUMBER,22], "E"."EMPLOYEE_ID"[NUMBER,22],
           "E"."FIRST_NAME"[VARCHAR2,20], "E"."LAST_NAME"[VARCHAR2,25],
           "E"."EMAIL"[VARCHAR2,25], "E"."PHONE_NUMBER"[VARCHAR2,20], "E"."HIRE_DATE"[DATE,7],
           "E"."JOB_ID"[VARCHAR2,10], "E"."SALARY"[NUMBER,22],
           "E"."COMMISSION_PCT"[NUMBER,22], "E"."MANAGER_ID"[NUMBER,22]
       5 - "E"."EMPLOYEE_ID"[NUMBER,22], "E"."FIRST_NAME"[VARCHAR2,20],
           "E"."LAST_NAME"[VARCHAR2,25], "E"."EMAIL"[VARCHAR2,25],
           "E"."PHONE_NUMBER"[VARCHAR2,20], "E"."HIRE_DATE"[DATE,7],
           "E"."JOB_ID"[VARCHAR2,10], "E"."SALARY"[NUMBER,22],
           "E"."COMMISSION_PCT"[NUMBER,22], "E"."MANAGER_ID"[NUMBER,22],
           "E"."DEPARTMENT_ID"[NUMBER,22]
    68 rows selected.
    /

    "outline data" are a set of hints that enforce the use of the given plan.
    The best source on interpreting plans (I know) is: http://antognini.ch/papers/InterpretingExecutionPlans_20091017.pdf
    Regards
    Martin

  • Help with interpreting explain plan (dbms_xplan) output

    Hi all,
    I'm trying to get to grips with reading and interpreting the explain plan or dbms_xplan output, and so I hope someone can help with the output below.
    So, with the explain shown below, does it mean that...
    a) it starts with step 8 and sends all rows to the nested loop in step 5
    b) it only sends (or thinks it sends) 1 row to step 5 from step 8
    c) For each row supplied from step 5, there will be an index lookup at step 8 to access the table at step 6
    d) Step 8 only gets (or think it gets) 1 row
    If it does mean that only 1 row is expected by the optimizer, and yet the full table scan should return 150,000 records, and the table has up to date statistiucs, what else would cause the cardinality to be so far off?
    If it doesn't mean it will return 1 row then what does it mean ?
    | Id  | Operation                           | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                    |                                |       |       |   945 (100)|          |
    |   1 |  SORT GROUP BY                      |                                |     1 |   283 |   945   (3)| 00:00:05 |
    |*  2 |   FILTER                            |                                |       |       |            |          |
    |   3 |    NESTED LOOPS                     |                                |       |       |            |          |
    |   4 |     NESTED LOOPS                    |                                |     1 |   283 |   944   (3)| 00:00:05 |
    |   5 |      NESTED LOOPS                   |                                |     1 |   108 |   929   (3)| 00:00:05 |
    |*  6 |       MAT_VIEW ACCESS FULL          | DEMOGRAPHICS_MV                |     1 |    97 |   927   (3)| 00:00:05 |
    |*  7 |       MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV                       |     1 |    11 |     2   (0)| 00:00:01 |
    |*  8 |        INDEX RANGE SCAN             | ORG_MV_IDX1                    |     1 |       |     1   (0)| 00:00:01 |
    |*  9 |      INDEX RANGE SCAN               | PAY_IDX8                       |   252 |       |     4   (0)| 00:00:01 |
    |* 10 |     TABLE ACCESS BY INDEX ROWID     | PAY_ALL                        |     1 |   175 |    15   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
          8 - access("ORG_MV"."ORG_ID"="DEMO_MV"."ORG_ID")Many thanks for your help.

    Thank you Hemant and rp0428,
    I read through that white paper which was really useful.
    I ran query using GATHER_PLAN_STATISTICS and go tthe Estimate and Actual rows - wow - it is a long way out!!
    | Id  | Operation                           | Name                           | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT                    |                                |      1 |        |       |   945 (100)|          |      0 |00:18:11.39 |    2552K|    361K|       |       |          |
    |   1 |  SORT GROUP BY                      |                                |      1 |      1 |   283 |   945   (3)| 00:00:05 |      0 |00:18:11.39 |    2552K|    361K|  1024 |  1024 |          |
    |*  2 |   FILTER                            |                                |      1 |        |       |            |          |      0 |00:18:11.39 |    2552K|    361K|       |       |          |
    |   3 |    NESTED LOOPS                     |                                |      1 |        |       |            |          |      0 |00:18:11.39 |    2552K|    361K|       |       |          |
    |   4 |     NESTED LOOPS                    |                                |      1 |      1 |   283 |   944   (3)| 00:00:05 |     44M|00:04:59.03 |     598K|  63442 |       |       |          |
    |   5 |      NESTED LOOPS                   |                                |      1 |      1 |   108 |   929   (3)| 00:00:05 |    109K|00:00:01.73 |    7807 |      7 |       |       |          |
    |*  6 |       MAT_VIEW ACCESS FULL          | DEMOGRAPHICS_MV                |      1 |      1 |    97 |   927   (3)| 00:00:05 |    126K|00:00:00.26 |    5417 |      1 |       |       |          |
    |*  7 |       MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV                       |    126K|      1 |    11 |     2   (0)| 00:00:01 |    109K|00:00:01.27 |    2390 |      6 |       |       |          |
    |*  8 |        INDEX RANGE SCAN             | ORG_MV_IDX1                    |    126K|      1 |       |     1   (0)| 00:00:01 |    126K|00:00:00.69 |    2023 |      6 |       |       |          |
    |*  9 |      INDEX RANGE SCAN               | PAY_IDX8                       |    109K|    252 |       |     4   (0)| 00:00:01 |     44M|00:04:03.07 |     590K|  63435 |       |       |          |
    |* 10 |     TABLE ACCESS BY INDEX ROWID     | PAY_ALL                        |     44M|      1 |   175 |    15   (0)| 00:00:01 |      0 |00:13:09.85 |    1954K|    297K|       |       |          |
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------When I unravel the WHERE clause and remove the decode(nvl statements (which only evaluate the passed in parameters and provide default values where they are NULL) I get a much better plan and values
    | Id  | Operation                        | Name                           | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT                 |                                |      1 |        |       |   157K(100)|          |      0 |00:00:43.10 |     343K|  45190 |       |       |          |
    |   1 |  SORT GROUP BY                   |                                |      1 |      1 |   283 |   157K  (1)| 00:13:47 |      0 |00:00:43.10 |     343K|  45190 |  1024 |  1024 |          |
    |   2 |   NESTED LOOPS                   |                                |      1 |        |       |            |          |      0 |00:00:43.10 |     343K|  45190 |       |       |          |
    |   3 |    NESTED LOOPS                  |                                |      1 |      1 |   283 |   157K  (1)| 00:13:47 |      0 |00:00:43.10 |     343K|  45190 |       |       |          |
    |*  4 |     HASH JOIN                    |                                |      1 |      1 |   272 |   157K  (1)| 00:13:47 |      0 |00:00:43.10 |     343K|  45190 |   720K|   720K|  171K (0)|
    |*  5 |      TABLE ACCESS BY INDEX ROWID | PAY_ALL                        |      1 |      2 |   350 |   156K  (1)| 00:13:43 |      0 |00:00:43.10 |     343K|  45190 |       |       |          |
    |*  6 |       INDEX RANGE SCAN           | PAY_IDX7                       |      1 |   3596K|       | 15565   (1)| 00:01:22 |   7251K|00:00:50.88 |   45190 |  45190 |       |       |          |
    |*  7 |      MAT_VIEW ACCESS FULL        | DEMOGRAPHICS_MV                |      0 |    126K|    11M|   919   (2)| 00:00:05 |      0 |00:00:00.01 |       0 |      0 |       |       |          |
    |*  8 |     INDEX RANGE SCAN             | ORG_MV_IDX1                    |      0 |      1 |       |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |       |       |          |
    |*  9 |    MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV                       |      0 |      1 |    11 |     2   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |       |       |          |
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Even though the result set is zero, the time to establish this came down from 35 minutes to 30 seconds and the plan has changed and is using a different index now!
    Thanks for your help!

  • Explain plan, Oracle 10g, AWR, ASH etc etc

    Hi,
    I'm obviously not searching on the right terms but using one of the following : AWR, ASH, ADDM, isn't it possible to get the explain plan for a certain SQL_ID after the fact?
    I was sure that using ash and specifying the SQL_ID that one could have the explain plan, but I don't have it in the ASH Report. We don't have Grid in place, only snapshots taken every hour.
    cheers.

    Thankyou both for your very quick replies, just what I needed.
    Edited by: mattyb on Mar 25, 2009 2:06 PM

  • Query tunning in Oracle using Explain Plan

    Adding to my below question: I have now modified the query and the path shownby 'Explain plan' has reduced. The 'Time' column of plan_table is also showing much lesser value. However, some people are suggesting me to consider the time required by the query to execute on Toad. Will it be practical? Please help!!
    Hi, I am using Oracle 11g. I need to optimize a Select query(Need to minimize the execution time). I need to know how 'Explain Plan' would help me. I know how to use Explain Plan command. I refer Plan_table table to see the details of the plan. Please guide me regarding which columns of the Plan_table should be considered while modifying the query for optimization. Some people say, 'Time' column should be considered, some say 'Bytes' etc. Some suggest on minimizing the full table scans, while some people say that I should minimize the total no. operations (less no. of rows should be displayed in Plan_table). As per an experienced friend of mine, full table scans should be reduced (for e.g. if there are 5 full table scans in the plan, then try to reduce them to less than 5. ). However, if I consider any full table scan operation in the plan_table, its shows value of 'time' column as only 1 which is very very less. Does this mean the full scan is actually taking very less time?? If yes, then this means full table scans are very fast in my case and no need to work on them. Some articles suggest that plan shown by 'Explain Plan' command is not necessarily followed while executing the query. So what should I look for then? How should I optimize the query and how will I come to know that it's optimized?? Please help!!...
    Edited by: 885901 on Sep 20, 2011 2:10 AM

    885901 wrote:
    Hi, I am using Oracle 11g. I need to optimize a Select query(Need to minimize the execution time). I need to know how 'Explain Plan' would help me. I know how to use Explain Plan command. I refer Plan_table table to see the details of the plan. Please guide me regarding which columns of the Plan_table should be considered while modifying the query for optimization. Some people say, 'Time' column should be considered, some say 'Bytes' etc. Some suggest on minimizing the full table scans, while some people say that I should minimize the total no. operations (less no. of rows should be displayed in Plan_table). As per an experienced friend of mine, full table scans should be reduced (for e.g. if there are 5 full table scans in the plan, then try to reduce them to less than 5. ). However, if I consider any full table scan operation in the plan_table, its shows value of 'time' column as only 1 which is very very less. Does this mean the full scan is actually taking very less time?? If yes, then this means full table scans are very fast in my case and no need to work on them. Some articles suggest that plan shown by 'Explain Plan' command is not necessarily followed while executing the query. So what should I look for then? How should I optimize the query and how will I come to know that it's optimized?? Please help!!...how fast is fast enough?

  • What are the privileges required for explain plan in Oracle 11g database

    I am facing the problem in doing a explain plan for a view in Oracle 11g database. When I select from the view like this:
    select * from zonewisearpu
    It does a select on the view but when I give explain plan like
    explain plan for
    select * from zonewisearpu
    I get the error like insufficient privileges.
    Please let me know if things are getting missed out as I guess system level privileges are required to execute this.
    I hope, my question is clear.
    It’s a humble request to revert urgently if possible as I need to complete a task and do not know the way out.
    Regards

    975148 wrote:
    Thanks for your reply. I have found out that an explain plan is possible on the user's own objects and is not possible on the granted objects from a different schema. For eg, if I do a explain plan on a view querying on tables from a different view, it would not allow the explain plan to proceed. This could mean that explain plan needs different privileges than just a select.
    Requesting for a revert to this.
    Here is a simple test case that I have perfomed
    SQL> create user test1 identified by test1;
    User created.
    SQL> create user test2 identified by test1;
    User created.
    SQL> grant connect, resource to test1,test2;
    Grant succeeded.
    SQL> create table test1.tab1 as select * from v$session;
    Table created.
    SQL> connect test2/test1
    Conencted.
    SQL> show user
    USER is "TEST2"
    SQL>
    SQL> explain plan for
      2  select sid,serial#,status,username from test1.tab1 where username<> '';
    Explained.
    SQL>
    So, as can be seen I am able to do a explain plan from user test2 for tables belong to user test1.
    As far as privileges are concerned, following is the list
    SQL> select * from dba_role_privs where grantee in ('TEST1','TEST2') order by 1;
    GRANTEE                        GRANTED_ROLE                   ADM DEF
    TEST1                          CONNECT                        NO  YES
    TEST1                          RESOURCE                       NO  YES
    TEST2                          CONNECT                        NO  YES
    TEST2                          RESOURCE                       NO  YES
    SQL>
    SQL> select grantee,owner,table_name,privilege from dba_tab_privs where grantee in ('TEST1','TEST2') order by 1;
    GRANTEE    OWNER      TABLE_NAME           PRIVILEGE
    TEST2      TEST1      TAB1                 SELECT
    SQL>
    SQL>  select * from dba_sys_privs where grantee in ('TEST1','TEST2') order by 1;
    GRANTEE    PRIVILEGE                      ADM
    TEST1      UNLIMITED TABLESPACE           NO
    TEST2      UNLIMITED TABLESPACE           NO
    SQL>

  • 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

  • "Explain Plan" in Oracle SQL Developer is greyed out

    Hi all,
    I know this is not the right place to post this, but I have look around and do not know where to post question about Oracle SQL Developer - I presume this tool is also discussed here in this forum.
    My question is very simple (I presume):
    1. I installed Oracle SQL Developer 3.0.04.
    2. I added a new DB connection to a DB hosted in one of my servers in the LAN.
    3. However, when I am writing some SQL queries, I intend to use the "Explain Plan" feature, but it is being greyed out (disabled).
    4. How can I enable it back?

    Hello,
    {forum:id=260}
    Regards
    Marcus

  • Oracle rownum wrong explain plan

    SCOTT@oracle10g>create table t as select * from dba_objects;
    Table created.
    SCOTT@oracle10g>alter table t modify CREATED date not null;
    Table altered.
    SCOTT@oracle10g>insert into t select * from t;
    50416 rows created.
    SCOTT@oracle10g>insert into t select * from t;
    100832 rows created.
    SCOTT@oracle10g>insert into t select * from t;
    201664 rows created.
    SCOTT@oracle10g>commit;
    Commit complete.
    SCOTT@oracle10g>create index t_created on t(created) nologging;
    Index created.
    SCOTT@oracle10g>select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
    PL/SQL Release 10.2.0.3.0 - Production
    CORE    10.2.0.3.0      Production
    TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
    NLSRTL Version 10.2.0.3.0 - Production
    SCOTT@oracle10g>set autot trace
    SCOTT@oracle10g>select t.owner,t.object_name   from
      2  (select rid from (
      3  select rownum rn,rid from
      4  (select rowid rid from t order by created)
      5  where rownum<100035)
      6  where rn>100000) h, t
      7  where t.rowid=h.rid;
    34 rows selected.
    Execution Plan
    Plan hash value: 3449471415
    | Id  | Operation           | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| T
    ime     |
    |   0 | SELECT STATEMENT    |           |   100K|    11M|       |  4776   (2)| 0
    0:00:58 |
    |*  1 |  HASH JOIN          |           |   100K|    11M|  3616K|  4776   (2)| 0
    0:00:58 |
    |*  2 |   VIEW              |           |   100K|  2442K|       |  1116   (2)| 0
    0:00:14 |
    |*  3 |    COUNT STOPKEY    |           |       |       |       |            |
            |
    |   4 |     VIEW            |           |   440K|  5157K|       |  1116   (2)| 0
    0:00:14 |
    |   5 |      INDEX FULL SCAN| T_CREATED |   440K|  9024K|       |  1116   (2)| 0
    0:00:14 |
    |   6 |   TABLE ACCESS FULL | T         |   440K|    39M|       |  1237   (2)| 0
    0:00:15 |
    Predicate Information (identified by operation id):
       1 - access("T".ROWID="RID")
       2 - filter("RN">100000)
       3 - filter(ROWNUM<100035)
    Note
       - dynamic sampling used for this statement
    Statistics
              0  recursive calls
              0  db block gets
           5814  consistent gets
              0  physical reads
              0  redo size
           1588  bytes sent via SQL*Net to client
            422  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             34  rows processed   
    here ,oracle don't choose the best explain plan ,I think becase  oracle compute cadinality 100k ,so it don't choose nest loop,why oracle can't compute cardinality 35 here ??
    |*  2 |   VIEW              |           |   100K|  2442K|       |  1116   (2)| 0
    SCOTT@oracle10g>select  t.owner,t.object_name   from t where rowid in
      2      (select rid from (
      3      select rownum rn,rid from
      4      (select rowid rid from t order by created)
      5      where rownum<100035)
      6      where rn>100000)
      7 
    SCOTT@oracle10g>/
    34 rows selected.
    Execution Plan
    Plan hash value: 1566335206
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T
    ime     |
    |   0 | SELECT STATEMENT            |           |     1 |   107 |  1586   (2)| 0
    0:00:20 |
    |   1 |  NESTED LOOPS               |           |     1 |   107 |  1586   (2)| 0
    0:00:20 |
    |   2 |   VIEW                      | VW_NSO_1  |   100K|  1172K|  1116   (2)| 0
    0:00:14 |
    |   3 |    HASH UNIQUE              |           |     1 |  2442K|            |
            |
    |*  4 |     VIEW                    |           |   100K|  2442K|  1116   (2)| 0
    0:00:14 |
    |*  5 |      COUNT STOPKEY          |           |       |       |            |
            |
    |   6 |       VIEW                  |           |   440K|  5157K|  1116   (2)| 0
    0:00:14 |
    |   7 |        INDEX FULL SCAN      | T_CREATED |   440K|  9024K|  1116   (2)| 0
    0:00:14 |
    |   8 |   TABLE ACCESS BY USER ROWID| T         |     1 |    95 |     1   (0)| 0
    0:00:01 |
    Predicate Information (identified by operation id):
       4 - filter("RN">100000)
       5 - filter(ROWNUM<100035)
    Note
       - dynamic sampling used for this statement
    Statistics
              0  recursive calls
              0  db block gets
            301  consistent gets
              0  physical reads
              0  redo size
           1896  bytes sent via SQL*Net to client
            422  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             34  rows processed
    SCOTT@oracle10g>select /*+ordered use_nl(t)*/ t.owner,t.object_name   from
      2  (select rid from (
      3  select rownum rn,rid from
      4  (select rowid rid from t order by created)
      5  where rownum<100035)
      6  where rn>100000) h, t
      7  where t.rowid=h.rid;
    34 rows selected.
    Execution Plan
    Plan hash value: 3976541160
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| T
    ime     |
    |   0 | SELECT STATEMENT            |           |   100K|    11M|   101K  (1)| 0
    0:20:16 |
    |   1 |  NESTED LOOPS               |           |   100K|    11M|   101K  (1)| 0
    0:20:16 |
    |*  2 |   VIEW                      |           |   100K|  2442K|  1116   (2)| 0
    0:00:14 |
    |*  3 |    COUNT STOPKEY            |           |       |       |            |
            |
    |   4 |     VIEW                    |           |   440K|  5157K|  1116   (2)| 0
    0:00:14 |
    |   5 |      INDEX FULL SCAN        | T_CREATED |   440K|  9024K|  1116   (2)| 0
    0:00:14 |
    |   6 |   TABLE ACCESS BY USER ROWID| T         |     1 |    95 |     1   (0)| 0
    0:00:01 |
    Predicate Information (identified by operation id):
       2 - filter("RN">100000)
       3 - filter(ROWNUM<100035)
    Note
       - dynamic sampling used for this statement
    Statistics
              0  recursive calls
              0  db block gets
            304  consistent gets
              0  physical reads
              0  redo size
           1588  bytes sent via SQL*Net to client
            422  bytes received via SQL*Net from client
              4  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
             34  rows processed  

    jinyu wrote:
    Thanks for your great reply and posting ,could you tell me why subquery has the least cost here ??
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 107 | 1586 (2)| 00:00:20 |
    | 1 | NESTED LOOPS | | 1 | 107 | 1586 (2)| 00:00:20 |
    | 2 | VIEW | VW_NSO_1 | 100K| 1172K| 1116 (2)| 00:00:14 |
    | 3 | HASH UNIQUE | | 1 | 2442K| | |
    |* 4 | VIEW | | 100K| 2442K| 1116 (2)| 00:00:14 |
    |* 5 | COUNT STOPKEY | | | | | |
    | 6 | VIEW | | 440K| 5157K| 1116 (2)| 00:00:14 |
    | 7 | INDEX FULL SCAN | T_CREATED | 440K| 9024K| 1116 (2)| 00:00:14 |
    | 8 | TABLE ACCESS BY USER ROWID| T | 1 | 95 | 1 (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------->
    You'll notice that as a result of a "driving" IN subquery Oracle has done a hash unique operation (line 3) on the rowids produced by the subquery. At this point the optimizer has lost all knowledge of the number of distinct values for that data column in the subquery and come back with the cardinality of one. The re-appearance of 100K as the cardinality in line 2 is an error, but I don't think the optimizer has used that value in later arithmetic.
    Given the cardinality of one, the obvious path into the T table is a nested loop.
    The same type of probelm appears when you use the table() operator in joins - you can use the cardinality() hint to try an tell Oracle how many rows the table() will produce, but that doesn't tell it how many distinct values there are in join columns - and that's an important detail when you work out the join cardinality and method).
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    http://www.jlcomp.demon.co.uk
    To post code, statspack/AWR report, execution plans or trace files, start and end the section with the tag {noformat}{noformat} (lowercase, curly brackets, no spaces) so that the text appears in fixed format.
    "Science is more than a body of knowledge; it is a way of thinking"
    Carl Sagan                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Explain plan cost it increases after migrating Oracle 9.2.0 to 10.2.0.3

    Hi:
    Recently the migration was made, we are testing (I'm developer) the performance in some querys, but the majority is but slow,I do not understand the reason because the new equipment has processing capacity much more.
    for example , a report , in 9i it is executed in 45 segs, in 10G it is executed in 10 minutes!!!
    Another example: the next explain plan, it's the same query and the same parameters . In oracle 9i COST=799 In Oracle 10G COST=2337
    What happens? Any idea?
    In oracle 9i COST=799
    SELECT STATEMENT Hint=HINT: FIRST_ROWS 1 799
    SORT GROUP BY 1 74 799
    VIEW 1 74 786
    SORT GROUP BY 1 100 786
    TABLE ACCESS BY INDEX ROWID SMRPCMT 1 27 1
    NESTED LOOPS 1 100 774
    NESTED LOOPS 3 219 773
    NESTED LOOPS 3 177 772
    NESTED LOOPS 3 171 771
    NESTED LOOPS 3 123 770
    TABLE ACCESS BY INDEX ROWID SFBETRM 7 K 73 K 22
    INDEX RANGE SCAN SFBETRM_KEY_INDEX2 7 K 24
    TABLE ACCESS BY INDEX ROWID SGBSTDN 1 31 1
    INDEX UNIQUE SCAN PK_SGBSTDN 1
    TABLE ACCESS BY INDEX ROWID STVMAJR 1 16 1
    INDEX UNIQUE SCAN PK_STVMAJR 1
    TABLE ACCESS BY INDEX ROWID STVCAMP 1 2 1
    INDEX UNIQUE SCAN PK_STVCAMP 1
    INDEX RANGE SCAN SMRPATR_KEY_INDEX 1 14 1
    INDEX RANGE SCAN SMRPCMT_KEY_INDEX 1 1
    In Oracle 10G COST=2337
    SELECT STATEMENT Hint=FIRST_ROWS 1 2337
    SORT GROUP BY 1 66 2337
    VIEW 1 66 2336
    SORT GROUP BY 1 158 2336
    NESTED LOOPS 1 158 2335
    NESTED LOOPS 1 142 2334
    NESTED LOOPS 1 140 2333
    NESTED LOOPS 1 126 2332
    NESTED LOOPS 3 297 2330
    TABLE ACCESS BY INDEX ROWID SFBETRM 7 K 73 K 67
    INDEX RANGE SCAN SFBETRM_KEY_INDEX2 7 K 6
    TABLE ACCESS BY INDEX ROWID SGBSTDN 1 89 1
    INDEX UNIQUE SCAN PK_SGBSTDN 1 1
    TABLE ACCESS BY INDEX ROWID SMRPCMT 1 27 1
    INDEX RANGE SCAN SMRPCMT_KEY_INDEX 1 1
    INDEX RANGE SCAN SMRPATR_KEY_INDEX 1 14 1
    TABLE ACCESS BY INDEX ROWID STVCAMP 1 2 1
    INDEX UNIQUE SCAN PK_STVCAMP 1 1
    TABLE ACCESS BY INDEX ROWID STVMAJR 1 16 1
    INDEX UNIQUE SCAN PK_STVMAJR 1 1
    Thank you so much by advance.
    (sorry by my bad english)

    "Cost", as determined by the CBO, is a relative number, not an absolute number. A "cost" of 799 in 9i is not the same as a "cost" of 799 in 10g.
    The CBO is 10g is substantially different as compared to 9i. Performance issues encountered after the upgrade are not uncommon. Pl refer to these MOS Doc to help troubleshoot your issue -
    754931.1 - Cost Based Optimizer - Common Misconceptions and Issues - 10g and Above
    466181.1 - 10g Upgrade Companion
    I would also recommend you upgrade to 10.2.0.4, as it is the latest and most stable version of 10g.
    HTH
    Srini

  • Explain plan for timesten and Oracle

    we have a base table in our Oracle 10g database. We created a DSN for this in timesten 7.0 database and are able to connect. Now we have created 3 materialized views in timesten on top of the Oracle Base Table. How can we get the explain plan in timesten to find out when the table is being called by a custom java application, the materialized views are being used or not ? Please advice

    Hi Can you help me in this regards,
    i am getting the following error. Can you tell me how can i get rid of them?
    Command> call ttcachestart();
    15001: User lacks privilege ADMIN

  • Oracle Hint not causing any change to explain plan

    Hi,
    I was facing a problem about ORA-00600 for using Connect by Prior query,
    details of which are at -
    Connect by Prior - ORA-00600: internal error code, arguments: [kkqcbydrv:1
    As is documented by Oracle, workaround for this is to use /*+ NO_UNNEST */ in query.
    I displayed the explain plan for original query and after putting hint in query.
    There is no difference in the explain plans, I am a starter for explain plans and don't know much of it.
    But shouldn't the hint cause some change in explain plan?
    Even the hash values as mentioned in explain plans are same.
    Thanks in advance.
    Av.

    Perhaps it would help if you put the query (with the hint) and the explain plan here.

  • Interpreting the Explain plan

    DB version : 10.2.0.4
    After looking for Full Table Scan (in Large tables) , what is the next thing i should be looking for in an Explain Plan?

    Take the explain plan as an idea a tourist has to collect a bunch of stuff in your hometown. You ( as a local guy) will see quite quickly if the idea of collecting everything on the main routes in big shops by car (hash join) or doing a walk in one or two streets with small shops (nested loop) will perform better. Stangers will not.
    ORACLE already knows more about the data than a tourist about your hometome, so if it uses a method which is "suboptimal" it needs someone with good knowlage about the data to do better. So make sure you know your datamodel, contents, indexes, data and then you can help ORACLE with additional indexes, hints etc. without knowlege every plan of ORACLE can not be juged.

  • Interpretation of Explain Plan

    Hi All,
    I am trying to optimize my query. Can anybody tell me where can I get documentation for How to interpret the output Generated by Explain Plan.
    TIA
    Dharmesh Patel

    Hi,
    You can find some useful documents on metalink, for example try Note:32951.1. Try searching on key words such as "Explain Plan" and "Optimiser".
    HTH,
    Gerard Kelly

Maybe you are looking for