What is a Bad Execution Plan?

First sorry for a general question.
For example, if we have identified a badly performing SQL, and have extracted its execution plan then what to look for to know that the plan is not the optimal one?
regards

I am thankful to all for very insightful answer to a very general question. Thanks, highly appreciate them.
Today I was asked to look at few queries, which were performing badly, i.e. taking too long a time to complete few days ago. I have posted detail of that thread here:
Poorly Performing SQL Queries and AWR
I am pasting just an execution plan here as an example for your kind review, and wondering that in the light of above suggestions how should one proceed about it:
| Id  | Operation                            | Name                   | Rows  | Bytes | Cost (%CPU)|
Time     |
|   0 | SELECT STATEMENT                     |                        |       |       |  9628 (100)|
          |
|   1 |  VIEW                                |                        |    73 | 58546 |  9628   (1)|
00:01:56 |
|   2 |   WINDOW SORT PUSHED RANK            |                        |    73 | 22630 |  9628   (1)|
00:01:56 |
|   3 |    FILTER                            |                        |       |       |            |
          |
|   4 |     NESTED LOOPS                     |                        |    73 | 22630 |  9627   (1)|
00:01:56 |
|   5 |      NESTED LOOPS                    |                        |    73 | 20586 |  9554   (1)|
00:01:55 |
|   6 |       NESTED LOOPS OUTER             |                        |    72 | 15552 |  9482   (1)|
00:01:54 |
|   7 |        NESTED LOOPS                  |                        |    72 | 13320 |  9410   (1)|
00:01:53 |
|   8 |         NESTED LOOPS                 |                        |    72 | 12168 |  9338   (1)|
00:01:53 |
|   9 |          NESTED LOOPS                |                        |  4370 |   277K|    29   (0)|
00:00:01 |
|  10 |           TABLE ACCESS BY INDEX ROWID| test_ORG                |     1 |    34 |     2   (0)|
00:00:01 |
|  11 |            INDEX UNIQUE SCAN         | test_ORG_PK             |     1 |       |     1   (0)|
00:00:01 |
|  12 |           TABLE ACCESS FULL          | test_USER               |  4370 |   132K|    27   (0)|
00:00:01 |
|  13 |          TABLE ACCESS BY INDEX ROWID | REF_CLIENT_FOO_ACCT   |     1 |   104 |     7   (0)|
00:00:01 |
|  14 |           INDEX RANGE SCAN           | RCFA_test_ORG_IDX       |   165 |       |     2   (0)|
00:00:01 |
|  15 |         TABLE ACCESS BY INDEX ROWID  | test_ACCOUNT            |     1 |    16 |     1   (0)|
00:00:01 |
|  16 |          INDEX UNIQUE SCAN           | test_CUSTODY_ACCOUNT_PK |     1 |       |     0   (0)|
          |
|  17 |        TABLE ACCESS BY INDEX ROWID   | test_USER               |     1 |    31 |     1   (0)|
00:00:01 |
|  18 |         INDEX UNIQUE SCAN            | test_USER_PK_IDX        |     1 |       |     0   (0)|
          |
|  19 |       TABLE ACCESS BY INDEX ROWID    | REF_FOO               |     1 |    66 |     1   (0)|
00:00:01 |
|  20 |        INDEX UNIQUE SCAN             | REF_FOO_PK            |     1 |       |     0   (0)|
          |
|  21 |      TABLE ACCESS BY INDEX ROWID     | REF_FOO_FAMILY        |     1 |    28 |     1   (0)|
00:00:01 |
PLAN_TABLE_OUTPUT
|  22 |       INDEX UNIQUE SCAN              | REF_FOO_FAMILY_PK     |     1 |       |     0   (0)|
          |
40 rows selected.
SQL>

Similar Messages

  • Bad execution plans when using parameters, subquery and partition by

    We have an issue with the following...
    We have this table:
    CREATE TABLE dbo.Test (
    Dt date NOT NULL,
    Nm int NOT NULL,
    CONSTRAINT PK_Test PRIMARY KEY CLUSTERED (Dt)
    This table can have data but it will not matter for this topic.
    Consider this query (thanks Tom Phillips for simplifying my question):
    declare @date as date = '2013-01-01'
    select *
    from (
    select Dt,
    row_number() over (partition by Dt order by Nm desc) a
    from Test
    where Dt = @date
    ) x
    go
    This query generates an execution plan with a clustered seek.
    Our queries however needs the parameter outside of the sub-query:
    declare @date as date = '2013-01-01'
    select *
    from (
    select Dt,
    row_number() over (partition by Dt order by Nm desc) a
    from Test
    ) x
    where Dt = @date
    go
    The query plan now does a scan followed by a filter on the date.
    This is extremely inefficient.
    This query plan is the same if you change the subquery into a CTE or a view (which is what we use).
    We have this kind of setup all over the place and the only way to generate a good plan is if we use dynamic sql to select data from our views.
    Is there any kind of solution for this?
    We have tested this (with the same result) on SQL 2008R2, 2012 SP1, 2014 CU1.
    Any help is appreciated.

    Hi Tom,
    Parameter sniffing is a different problem. A query plan is made based on the value which may be really off in the data distribution. We do have this problem as well e.g. when searching for today's data when the statistics think the table only has yesterday's
    data (a problem we have a lot involves the lack of sufficient amount of buckets in statistics objects).
    This problem is different.
    - It doesn't matter what the parameter value is.
    - You can reproduce this example with a fresh table. I.e. without statistics.
    - No matter what the distribution of data (or even if the statistics are correct), there is absolutely no case possible (in my example) where doing a scan followed by a filter should have better results than doing a seek.
    - You can't change the behavior with hints like "option(recompile)" or "optimize for".
    This problem has to do with the specific combination of "partition by" and the filter being done outside of the immediate query. Try it out, play with the code, e.g. move the where clause inside the subquery. You'll see what I mean.
    Thanks for responding.
    Michel

  • What Next After ETL Execution Plan Run in DAC

    Dear all,
    I am new in Oracle OBIEE, & want to integrate prebuilt KPIs of EBS R12.1.1 with OBIEE 7.9.6.1 I have run ETL execution Plan in DAC for "Financial Receivable" Subject Area.
    After this what is the next step to access in BI Answers or any other steps are involved Please help me. In which .rpd file financial Receivable exist so that I can see it through BI Administration tool.
    If Any one have a comprehensive document to integrate please forward me at [email protected]
    Regards,
    Yasir
    Edited by: Yasir_Oracle on Dec 22, 2010 1:55 AM

    Thanks in advance
    This is my custom task
    1. I have created Subject Area in Design view and added fact table
    2. In Execute view added the created subject area in first step and generated appropriate parameters in
    child and then tried to build in main tab
    I am trying to build execution plan for only one subject area and error is as follows
    MESSAGE:::NodeList size size cannot be less than 1
    EXCEPTION CLASS::: java.lang.IllegalArgumentException
    com.siebel.analytics.etl.graph.PosetMatrix.<init>(PosetMatrix.java:48)
    com.siebel.analytics.etl.graph.XNodeManager.generatePosetMatrix(XNodeManager.java:418)
    com.siebel.analytics.etl.execution.ExecutionPlanDesigner.generateRegularDependency(ExecutionPlanDesigner.java:858)
    com.siebel.analytics.etl.execution.ExecutionPlanDesigner.getExecutionPlanTasks(ExecutionPlanDesigner.java:686)
    com.siebel.analytics.etl.execution.ExecutionPlanDesigner.design(ExecutionPlanDesigner.java:1106)
    com.siebel.analytics.etl.client.view.table.EtlDefnTable.buildWithConfirmation(EtlDefnTable.java:230)
    com.siebel.analytics.etl.client.view.table.EtlDefnTable.build(EtlDefnTable.java:150)
    com.siebel.analytics.etl.client.view.table.EtlDefnTable.performOperation(EtlDefnTable.java:99)
    com.siebel.analytics.etl.client.view.table.BasicTable.actionPerformed(BasicTable.java:990)
    javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
    Regards,
    SMA

  • Can Oracle make mistakes while making execution plan?

    Env: Running Oracle DB 11g Rel 1.
    Is it possible that oracle may use a different execution plan for the same query depending on the environment where its running due to any reason. I am running an oracle report 6i/10g which has started to take too long to run but at the same time runs better/faster while in sql*plus or toad. Report has nothing more than a query (like: no pl/sql, or triggers with sqls).
    Is it also possible that depending on the different environment that runs the query or user profile, oracle might be using a different (may be bad) execution plan. Though at the same time database is same, no parameters are changed at run time explicitly by user or application. Base table of the query are all analyzed on regular basis.
    Or, is it possible that at some point in time in the past, the same query had a bad plan and oracle kept using it from the cache (though I can't find any doc which would support this). I think that estimated plan might be bad based on past statistics but actual plan shouldn't be same bad as estimated. Does clearing the cache help?
    Any insight or links to docs are appreciated.

    ocp9i wrote:
    Env: Running Oracle DB 11g Rel 1.
    Is it possible that oracle may use a different execution plan for the same query depending on the environment where its running due to any reason. That is after all what cost based optimisation is.. taking the existing factors into consideration for determining the execution plans. Different factors may apply for future executions of that SQL - which could mean a different execution plan.
    CBO does not mean that there will be a consistent-always-the-same execution plan for a SQL. It can and often will differ over time.
    I am running an oracle report 6i/10g which has started to take too long to run but at the same time runs better/faster while in sql*plus or toad.You cannot evaluate performance using elapsed execution time - that is a flawed approach. The very same query can run a lot faster after the 1st execution as the 1st execution did expensive physical I/O from disk. Subsequent execution of that query will find the data in the buffer cache and instead of physical I/O, do cheaper logical I/O.
    Also, reporting will typically include rendering. This is an added overhead that a plain SQL select in comparison will not have.
    So you need to be careful in how you match the performance of a query like this. There's a lot more to it than meets the eye.
    Or, is it possible that at some point in time in the past, the same query had a bad plan and oracle kept using it from the cache (though I can't find any doc which would support this). How do you know that this is a bad execution plan? How do you know that the report SQL uses a different execution plan than what your plain SQL select test does?
    If the query is exactly the same (proper shared SQL), then there will be a single execution plan for that query. The 1st time that the query is hard parsed, this execution plan is created. Subsequent processes/sessions will use the very same execution plan (soft parsing) until that cursor is aged from the Shared Pool.
    Thus if you are firing off an identical query via Reports and something like SQL*Plus.. chances are excellent that both is using the exact same execution plan.
    Any insight or links to docs are appreciated.Suggest that you look at the Oracle Concepts guide. You'll find it via http://tahiti.oracle.com

  • Several nested loop at the same level in an execution plan

    Hi, I am using 11gR2, and I've seen a execution plan in the trace of my SQL query (also shown in pl/sql explain plan) with 4 nested loops all at the same level, what does this mean?
    i.e.
    - SELECT STATEMENT, GOAL = FIRST_ROWS
    + NESTED LOOPS
    + NESTED LOOPS
    + NESTED LOOPS
    + NESTED LOOPS
    each NESTED LOOP can be expanded to 2 further actions, which make sense to me. e.g.
    + NESTED LOOPS
    + TABLE ACCESS BY INDEX ROWID
    + TABLE ACCESS BY INDEX ROWID
    THANKS
    Ye

    >
    why there are 4 Nested Loops
    what is the final result set for the SELECT statement come from (any one of the 4)
    the query run so slow in 11R2
    >
    So far you are the only one who knows what the query and execution plan are because you haven't posted them
    >
    Then you need to post the query, tell us what indexes are on the join columns and post the complete plan.
    >
    We can't even begin to explain why Oracle might have chosen the plan it did if we can't see the query and plan you want explained.
    And if we only see the plan we might be able to tell you what Oracle is doing but without knowing what indexes might be on the join columns and the filter criteria columns we can't tell you why Oracle chose the plan it chose.
    And the excerpt of the plan you did provide is incomplete. You removed the indenting possibly because you did not enclose it in 'code' tags (see the FAQ).
    >
    - SELECT STATEMENT, GOAL = FIRST_ROWS
    + NESTED LOOPS
    + NESTED LOOPS
    + NESTED LOOPS
    + NESTED LOOPS
    >
    There can't be four nested loops like that at the top level since the top level will be combining the result sets from it's children. A nested loop will have two children; like the last part you showed:
    >
    + NESTED LOOPS
    + TABLE ACCESS BY INDEX ROWID
    + TABLE ACCESS BY INDEX ROWID
    >
    The two 'TABLE ACCESS ...' will be indented on a normal plan.
    Without the query and plan there isn't much we can tell you.

  • One query - one database - different execution plan for different users.

    Hi everyone.
    I've encountered one of the strangest things I've ever seen with Oracle.  I'm hoping that someone else here has seen something like this before and solved it!  On an 11g database I have a query that runs differently depending on which user runs it.  If the owner of the tables or someone with the DBA role runs the query I get a perfect execution plan.  If someone else runs it, I get a really bad execution plan - though the query still executes.  So it almost seems like depending on who is running the query, the optimizer might not have access to the same statistics??  I'm really grasping at straws here - any help would be greatfully accepted!!!
    Here is the query and the two plans for it...
    On TASD as a General User (Bad execution plan) - CA17062 is USER
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0
    Connected as ca17062
    SQL> explain plan for
    select w.worker_id, w.worker_name
      from worker_v                   w,
           worker_cost_centre_v       c
    where w.worker_id = c.worker_id
       and c.effective_date <= trunc(sysdate)
       and c.expiration_date >= trunc(sysdate)
       and c.cost_centre = '100033'
       and pkg_taw_security.user_worker_access('CA17062',
                                               'TIMEKEEPER',
                                               w.worker_id,
                                               trunc(sysdate)) = 1
    order by w.worker_name;
    Explained
    Executed in 0.234 seconds
    PLAN_TABLE_OUTPUT
    Plan hash value: 1726112176
    | Id  | Pid | Ord | Operation                      | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 |     |   8 | SELECT STATEMENT               |                        |    18 |  1800 |   606   (1)| 00:00:01 |
    |   1 |   0 |   7 |  SORT ORDER BY                 |                        |    18 |  1800 |   606   (1)| 00:00:01 |
    |*  2 |   1 |   6 |   HASH JOIN                    |                        |    18 |  1800 |   605   (1)| 00:00:01 |
    |   3 |   2 |   3 |    VIEW                        | WORKER_COST_CENTRE_V   |    18 |   558 |    19   (0)| 00:00:01 |
    |*  4 |   3 |   2 |     TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL |    18 |   522 |    19   (0)| 00:00:01 |
    |*  5 |   4 |   1 |      INDEX RANGE SCAN          | WORKER_CC_CC_IDX       |    29 |       |     3   (0)| 00:00:01 |
    |*  6 |   2 |   5 |    VIEW                        | WORKER_V               |   161K|    10M|   584   (1)| 00:00:01 |
    |   7 |   6 |   4 |     TABLE ACCESS FULL          | WORKER_TBL             |   161K|  3466K|   584   (1)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("W"."WORKER_ID"="C"."WORKER_ID")
       4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
    PLAN_TABLE_OUTPUT
       5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
       6 - filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"W"."WORKER_ID",TRUN
                  C(SYSDATE@!))=1)
    About
      - XPlan v1.2 by Adrian Billington (http://www.oracle-developer.net)
    23 rows selected
    Executed in 0.577 seconds
    WORKER_ID WORKER_NAME
    123703    FADDEN, CLAYTON
    11131     HAHN, BRAD
    33811     HALL, MAUREEN
    53934     JANES, CATHERINE
    Executed in 35.241 seconds
    On TASD as the owner of the tables or as someone with the DBA role (Good Execution) - TAS is USER:
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0
    Connected as tas
    SQL> explain plan for
    select w.worker_id, w.worker_name
      from worker_v                   w,
           worker_cost_centre_v       c
    where w.worker_id = c.worker_id
       and c.effective_date <= trunc(sysdate)
       and c.expiration_date >= trunc(sysdate)
       and c.cost_centre = '100033'
       and pkg_taw_security.user_worker_access('CA17062',
                                               'TIMEKEEPER',
                                               w.worker_id,
                                               trunc(sysdate)) = 1
    order by w.worker_name;
    Explained
    Executed in 0.203 seconds
    PLAN_TABLE_OUTPUT
    Plan hash value: 3435904055
    | Id  | Pid | Ord | Operation                      | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 |     |   8 | SELECT STATEMENT               |                        |    18 |   918 |    38   (3)| 00:00:01 |
    |   1 |   0 |   7 |  SORT ORDER BY                 |                        |    18 |   918 |    38   (3)| 00:00:01 |
    |   2 |   1 |   6 |   NESTED LOOPS                 |                        |       |       |            |          |
    |   3 |   2 |   4 |    NESTED LOOPS                |                        |    18 |   918 |    37   (0)| 00:00:01 |
    |*  4 |   3 |   2 |     TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL |    18 |   522 |    19   (0)| 00:00:01 |
    |*  5 |   4 |   1 |      INDEX RANGE SCAN          | WORKER_CC_CC_IDX       |    29 |       |     3   (0)| 00:00:01 |
    |*  6 |   3 |   3 |     INDEX UNIQUE SCAN          | WORKER_PK              |     1 |       |     0   (0)| 00:00:01 |
    |   7 |   2 |   5 |    TABLE ACCESS BY INDEX ROWID | WORKER_TBL             |     1 |    22 |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
       5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
    PLAN_TABLE_OUTPUT
       6 - access("X"."WORKER_ID"="X"."WORKER_ID")
           filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"X"."WORKER_ID",TRUN
                  C(SYSDATE@!))=1)
    About
      - XPlan v1.2 by Adrian Billington (http://www.oracle-developer.net)
    23 rows selected
    Executed in 0.624 seconds
    WORKER_ID WORKER_NAME
    123703    FADDEN, CLAYTON
    11131     HAHN, BRAD
    33811     HALL, MAUREEN
    53934     JANES, CATHERINE
    Executed in 1.307 seconds
    THANKS!!!
    Cory Aston

    I reran the whole thing - with full declared view names and display_cursor.  Here are the results...
    On TASD as CA17062  (BAD EXECUTION PLAN)
    SQL> set linesize 160
    SQL> set serveroutput off
    SQL>
    SQL> select /*+ gather_plan_statistics */
      2         w.worker_id, w.worker_name
      3    from tas.worker_v                   w,
      4         tas.worker_cost_centre_v       c
      5   where w.worker_id = c.worker_id
      6     and c.effective_date <= trunc(sysdate)
      7     and c.expiration_date >= trunc(sysdate)
      8     and c.cost_centre = '100033'
      9     and tas_user.pkg_taw_security.user_worker_access('CA17062',
    10                                             'TIMEKEEPER',
    11                                             w.worker_id,
    12                                             trunc(sysdate)) = 1
    13   order by w.worker_name;
    WORKER_ID WORKER_NAME
    123703    FADDEN, CLAYTON
    11131     HAHN, BRAD
    33811     HALL, MAUREEN
    53934     JANES, CATHERINE
    SQL>
    SQL> select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));
    PLAN_TABLE_OUTPUT
    SQL_ID  gs5vtgany8vbv, child number 3
    select /*+ gather_plan_statistics */        w.worker_id, w.worker_name
    from tas.worker_v                   w,        tas.worker_cost_centre_v
          c  where w.worker_id = c.worker_id    and c.effective_date <=
    trunc(sysdate)    and c.expiration_date >= trunc(sysdate)    and
    c.cost_centre = '100033'    and tas_user.pkg_taw_security.user_worker_ac
    cess('CA17062',
    'TIMEKEEPER',                                            w.worker_id,
                                             trunc(sysdate)) = 1  order by
    w.worker_name
    Plan hash value: 1726112176
    | Id  | Operation                      | Name                   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT               |                        |      1 |        |      4 |00:00:18.52 |     947K|       |       |          |
    |   1 |  SORT ORDER BY                 |                        |      1 |      4 |      4 |00:00:18.52 |     947K|  2048 |  2048 | 2048  (0)|
    |*  2 |   HASH JOIN                    |                        |      1 |      4 |      4 |00:00:15.84 |     947K|  1348K|  1348K|  791K (0)|
    |   3 |    VIEW                        | WORKER_COST_CENTRE_V   |      1 |      4 |      4 |00:00:00.01 |      18 |       |       |          |
    |*  4 |     TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL |      1 |      4 |      4 |00:00:00.01 |      18 |       |       |          |
    |*  5 |      INDEX RANGE SCAN          | WORKER_CC_CC_IDX       |      1 |     29 |     21 |00:00:00.01 |       3 |       |       |          |
    |*  6 |    VIEW                        | WORKER_V               |      1 |    161K|      4 |00:00:15.84 |     946K|       |       |          |
    |   7 |     TABLE ACCESS FULL          | WORKER_TBL             |      1 |    161K|    160K|00:00:00.09 |    2135 |       |       |          |
    Predicate Information (identified by operation id):
       2 - access("W"."WORKER_ID"="C"."WORKER_ID")
       4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
       5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
       6 - filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"W"."WORKER_ID",TRUNC(SYSDATE@!))=1)
    Note
       - cardinality feedback used for this statement
    39 rows selected.
    SQL>
    On TASD as TAS: (GOOD EXECUTION PLAN)
    SQL> set serveroutput off
    SQL>
    SQL> select /*+ gather_plan_statistics */
      2         w.worker_id, w.worker_name
      3    from tas.worker_v                   w,
      4         tas.worker_cost_centre_v       c
      5   where w.worker_id = c.worker_id
      6     and c.effective_date <= trunc(sysdate)
      7     and c.expiration_date >= trunc(sysdate)
      8     and c.cost_centre = '100033'
      9     and tas_user.pkg_taw_security.user_worker_access('CA17062',
    10                                             'TIMEKEEPER',
    11                                             w.worker_id,
    12                                             trunc(sysdate)) = 1
    13   order by w.worker_name;
    WORKER_ID WORKER_NAME
    123703    FADDEN, CLAYTON
    11131     HAHN, BRAD
    33811     HALL, MAUREEN
    53934     JANES, CATHERINE
    SQL>
    SQL> select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));
    PLAN_TABLE_OUTPUT
    SQL_ID  gs5vtgany8vbv, child number 1
    select /*+ gather_plan_statistics */        w.worker_id, w.worker_name
    from tas.worker_v                   w,        tas.worker_cost_centre_v
          c  where w.worker_id = c.worker_id    and c.effective_date <=
    trunc(sysdate)    and c.expiration_date >= trunc(sysdate)    and
    c.cost_centre = '100033'    and tas_user.pkg_taw_security.user_worker_ac
    cess('CA17062',
    'TIMEKEEPER',                                            w.worker_id,
                                             trunc(sysdate)) = 1  order by
    w.worker_name
    Plan hash value: 3435904055
    | Id  | Operation                      | Name                   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT               |                        |      1 |        |      4 |00:00:00.01 |     185 |       |       |          |
    |   1 |  SORT ORDER BY                 |                        |      1 |      4 |      4 |00:00:00.01 |     185 |  2048 |  2048 | 2048  (0)|
    |   2 |   NESTED LOOPS                 |                        |      1 |        |      4 |00:00:00.01 |     185 |       |       |          |
    |   3 |    NESTED LOOPS                |                        |      1 |      4 |      4 |00:00:00.01 |     181 |       |       |          |
    |*  4 |     TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL |      1 |      4 |      4 |00:00:00.01 |      18 |       |       |          |
    |*  5 |      INDEX RANGE SCAN          | WORKER_CC_CC_IDX       |      1 |     29 |     21 |00:00:00.01 |       3 |       |       |          |
    |*  6 |     INDEX UNIQUE SCAN          | WORKER_PK              |      4 |      1 |      4 |00:00:00.01 |     163 |       |       |          |
    |   7 |    TABLE ACCESS BY INDEX ROWID | WORKER_TBL             |      4 |      1 |      4 |00:00:00.01 |       4 |       |       |          |
    Predicate Information (identified by operation id):
       4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
       5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
       6 - access("X"."WORKER_ID"="X"."WORKER_ID")
           filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"X"."WORKER_ID",TRUNC(SYSDATE@!))=1)
    Note
       - cardinality feedback used for this statement
    39 rows selected.
    SQL>

  • Bad explain plan for count(*)

    select count(*) from foo
    where flda = value and
    fldba like 'text'
    and contains(col,'some text') > 0
    takes long time - does not use domain index.
    If I replace count(*) w/*, runs like a champ, and uses domain index.
    null

    Define a "good" or a "bad" execution plan.
    See Wolfgang Breitling's Tuning by Cardinality Feedback:
    http://www.centrexcc.com/Tuning%20by%20Cardinality%20Feedback.pdf
    OBSERVATION
    IF AN ACCESS PLAN IS NOT OPTIMAL IT IS BECAUSE THE CARDINALITY ESTIMATE FOR ONE OR MORE OF
    THE ROW SOURCES IS GROSSLY INCORRECT."
    CONJECTURE
    THE CBO DOES AN EXCELLENT JOB OF FINDING THE BEST ACCESS PLAN FOR A GIVEN SQL PROVIDED
    IT IS ABLE TO ACCURATELY ESTIMATE THE CARDINALITIES OF THE ROW SOURCES IN THE PLANSo the flipside of that is that if you can identify executions plans where the estimates were not accurate (see DBMS_XPLAN.DISPLAY_CURSOR) then it is more llikely that a suboptimal plan was used and more optimal plans are possible.
    Edited by: Dom Brooks on Aug 21, 2012 1:06 PM
    link /text missing for some reason

  • Disabled execution plan still being picked up

    I already disabled the bad execution plan in the SQL baselines (ENABLED = NO), but still being picked up by the SQL. Why is that so?

    Hi Ramin,
    These are the results of show parameter optimizer
    SQL> show parameter optimizer;
    NAME                                 TYPE        VALUE
    optimizer_capture_sql_plan_baselines boolean     FALSE
    optimizer_dynamic_sampling           integer     4
    optimizer_features_enable            string      11.2.0.2
    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

  • What to look for in Execution plans ?

    Hi Pals,
    Assuming the query execution is slow , I have collected the xml plan. What should I look for in the actual execution plan . What are the top 10 things I need to watch out for?
    I know this is a broad and generic question but I am looking for anyone who is experienced in query tuning to answer this question.
    Thanks in Advance.

    Reading execution plans is a bit of an art. But a couple of things:
    1) Download and install SQL Sentry Plan Explorer (www.sqlsentry.net). This is a free tool that in msny cases gives a better experience to look at execution plans, particularly big and ugly ones.
    2) I usually look for the thickest arrows, as thickness indicates the number of rows being processed.
    3) Look for deviations between estimates and actual values, as these deviations are often the source for bad performance. In Plan Explorer, you can quickly flip between the too. In SSMS you need to look at the popup for every operator. (But again, it is
    the operator with fat arrows that are of most interest - and those before them.
    4) The way to read the plan is that the left-most operator asks the operators it is connected to for data. The net effect is that data flows from right to left, and the right-hand side if often more interesting.
    5) Don't pay much attention to the percentages about operator cost. These percentages are estimates only,
    not actual values. They are only reliable if the estimates are correct all the way through - and when you have a bad plan that is rarely the case.
    This was the overall advice. Then there is more specific one: are indexes being used when expected? Note that scans are necessarily not bad. Sometimes your problem is that you have a loop join + index seek, when you should have had two scans and a hash join.
    Try to get a grip of how you would process the query, if you had to do it manually. Does the plan match that idea?
    Erland Sommarskog, SQL Server MVP, [email protected]

  • What's the execution plan tell me?

    Hey everyone,
    I'm just looking at this execution plan and want to understand what it exactly tells me.. I could make a little sense of it. I would like someone to explain it to me please.
    Here it is:
    Predicate Information (identified by operation id):
    4 - access("A"."ATHLETEID"="ATHLETEID")
    5 - filter("CCODE"='AUS')
    Note
    - dynamic sampling used for this statement (level=2)
    Statistics
    32 recursive calls
    0 db block gets
    26289 consistent gets
    0 physical reads
    5664 redo size
    23496 bytes sent via SQL*Net to client
    936 bytes received via SQL*Net from client
    49 SQL*Net roundtrips to/from client
    2 sorts (memory)
    0 sorts (disk)
    717 rows processed ---> it has selected 717 tuples.
    I know the last one but not the rest. Looking forward to a detailed answer on this.

    >
    I'm just looking at this execution plan and want to understand what it exactly tells me.. I could make a little sense of it. I would like someone to explain it to me please.
    >
    Well you are the ONLY one looking at the plan because you didn't post it for us to look at.
    Can't comment on something we can't see.

  • What does cost mean in execution plan?

    What does a cost increase actually mean compared to the decrease of data that has to be processed?
    More details:
    I have 3 tables:
    - users
    - transaction types
    - user transactions
    I'm joining user transactions with transaction types for a particular user and aggregating some result from the transaction type table.
    Originally there was no index on the user transactions table containing both the user_id (on which is filtered) and the transaction id. This lead to a TABLE ACCESS and joining a lot of data for nothing. I created an index to contain both fields so that no more TABLE ACCESS is needed. It indeed reduced the amount of data to be merged and aggregated considerably, but the COST of the query went up! This I don't understand. (the query itself did not seem to take more/less time).
    What does a cost increase actually mean compared to the decrease of data that has to be processed?
    Below are the two execution plans:
    Execution plan with low cost and table access.
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=51 Card=1 Bytes=33)
    1 0 SORT (AGGREGATE)
    2 1 HASH JOIN (Cost=51 Card=283759 Bytes=9364047)
    3 2 TABLE ACCESS (BY INDEX ROWID) OF 'THIRD_PARTY_TRANSACT
    IONS' (Cost=2 Card=448 Bytes=8960)
    4 3 INDEX (RANGE SCAN) OF 'X_TP_TRANSACTIONS_USER' (NON-
    UNIQUE) (Cost=1 Card=448)
    5 2 INDEX (FAST FULL SCAN) OF 'X_ISP_TRANSACTIONS_TRID_FIN
    AL' (NON-UNIQUE) (Cost=4 Card=63339 Bytes=823407)
    Execution plan with only index join but high cost
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=272 Card=1 Bytes=28)
    1 0 SORT (AGGREGATE)
    2 1 HASH JOIN (Cost=272 Card=3287 Bytes=92036)
    3 2 INDEX (FAST FULL SCAN) OF 'X_TP_TRANSACTIONS_TRID_USER
    ID' (NON-UNIQUE) (Cost=21 Card=3287 Bytes=49305)
    4 2 INDEX (FAST FULL SCAN) OF 'X_ISP_TRANSACTIONS_TRID_FIN
    AL' (NON-UNIQUE) (Cost=4 Card=63339 Bytes=823407)

    when oracle parses and optimises a query it creates several execution plans and assigns a cost to each plan.
    It then uses this cost to compare these plans.
    But you can't use this cost as an indication of how "heavy" a query is, nor can you compare the costs between different queries.
    It is only a value used internally by oracle.
    greetings
    Freek D

  • What execution plan was used?

    Hi there
    How can I find out what execution plan was used for an SQL when it was executed as part of the batch-process at night? 10gR2 on ASM, RHEL 5.8 64bit.
    Best regards

    Are you using the enterprise edition?  Are you licensed to use the AWR?  If so, assuming that the query ran long enough to be captured in an AWR snapshot (which seems likely if you're asking this question), DBA_HIST_SQL_PLAN will have the plan information and DBA_HIST_SQLSTAT will tell you the plan_hash_value (or values) that were used for a particular SQL_ID in a particular SNAP_ID.  DBA_HIST_SNAPSHOT will tell you what SNAP_ID (or set of snap_id's) corresponds to whatever time period you are interested in.
    Justin

  • Whats d execution plan?

    whats d execution plan?
    where and how to check statistics of table?
    i am user of sqlplus and tod and having some knoledge of sql developer.
    plz...
    i search on net i got this command and i tryed i got belo lines shown as
    RCI5142 @ msedcl> set autotrace TRACEONLY EXPLAIN
    RCI5142 @ msedcl> select consumer_number from receipts where consumer_number not in (select consumer_number from consumer_master);
    Execution Plan
    0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2903788 Card=18126
    5 Bytes=2175180)
    1 0 FILTER
    2 1 TABLE ACCESS (FULL) OF 'RECEIPTS' (TABLE) (Cost=1153 Car
    d=181272 Bytes=2175264)
    3 1 INDEX (FAST FULL SCAN) OF 'PK_CON_NUMBER' (INDEX (UNIQUE
    )) (Cost=20 Card=1 Bytes=12)
    now can some one tell me about
    why simple script takes time to run..... as
    select consumer_number from receipts where consumer_number not in (select consumer_number from consumer_master);
    Edited by: 790948 on Aug 27, 2010 12:21 AM

    790948 wrote:
    whats d execution plan? Set of steps which would be used to run the query.
    where and how to check statistics of table?From the dba_tables view.
    i am user of sqlplus and tod and having some knoledge of sql developer.Please post next time the version of the db and o/s with the thread as well as check first in the http://tahiti.oracle.com .
    HTH
    Aman....

  • Oracle 10g Diff in execution plan query with binding var Vs without

    We recently did 10g upgrade. In 10g, execution plan differs for query with binding var(thru jdbc etc) Vs without it as given below. For query with binding var,
    it chooses poor execution plan(no index is used, full scan is done etc). everything worked fine in 9i. To rectify the problem, we have to hint query with right index,join etc. but i dont like this solution.
    I would rather prefer to correct database to choose right execution path instead of eacy query level. but not sure what causes the issue.
    Does anybody came across this issue? if so, Please share your experiences. Thanks for the help. Do let me know if you need more info.
    1. Query without binding bar:
    select * from test where col1 = :1 and col2 = :2
    1. Query without binding bar:
    select * from test where col1 = 'foo' and col2= 'bar'

    I am not an expert but in my humble opinion it is the developer's responsability to ensure the correct explain plan is used before deploying code to production, if the explain plan returned by the DB is bad, then the use of a hint is perfectly acceptable.
    Check this out: http://lcgapp.cern.ch/project/CondDB/snapshot/performance.html
    Excerpt:
    Bind variable peeking. If an SQL query contains bind variables, the optimal execution plan may depend on the values of those variables. When the Oracle query optimizer chooses the execution plan for such a query, it may indeed look at the values of all bind variables involved: this is known as "bind variable peeking".
    In summary, the execution plan used for a given SQL query cannot be predicted a priori because it depends on the presence and quality of statistics and on the values of bind variables used at the time the query was first executed (hard-parsed). As a consequence of this instability of execution plans, very different performances may be observed for the same SQL query. In COOL, this issue is addressed by adding Oracle hints to the queries, to make sure that the same (good) plan is used in all cases, even with unreliable statistics or unfavourable bind variables.
    Edited by: Rodolfo Ferrari on Jun 3, 2009 9:40 PM

  • Explain SQL Query execution plan: Oracle

    Dear Masters,
    Kindly help me to understand execution plan for an SQL statement. I have following SQL execution plan for a query in system. How should I interpret it. I thank You in advace for your guidance.
    SELECT STATEMENT ( Estimated Costs = 1.372.413 , Estimated #Rows = 0 )
           5 NESTED LOOPS
             ( Estim. Costs = 1.372.413 , Estim. #Rows = 3.125 )
             Estim. CPU-Costs = 55.798.978.498 Estim. IO-Costs = 1.366.482
               2 TABLE ACCESS BY INDEX ROWID MSEG
                 ( Estim. Costs = 1.326.343 , Estim. #Rows = 76.717 )
                 Estim. CPU-Costs = 55.429.596.575 Estim. IO-Costs = 1.320.451
                 Filter Predicates
                   1 INDEX RANGE SCAN MSEG~R
                     ( Estim. Costs = 89.322 , Estim. #Rows = 60.069.500 )
                     Search Columns: 1
                     Estim. CPU-Costs = 2.946.739.229 Estim. IO-Costs = 89.009
                     Access Predicates
               4 TABLE ACCESS BY INDEX ROWID MKPF
                 ( Estim. Costs = 1 , Estim. #Rows = 1 )
                 Estim. CPU-Costs = 4.815 Estim. IO-Costs = 1
                 Filter Predicates
                   3 INDEX UNIQUE SCAN MKPF~0
                     Search Columns: 3
                     Estim. CPU-Costs = 3.229 Estim. IO-Costs = 0
                     Access Predicates

    Hi Panjak,
    Yeahh, there's a huge unperformatic SQL statment, what I can see from this acces plan is:
    1 DBO decided to start the query on index R on MSEG, using only part of the index (only one column) with no good uniqueness, accessing disk IO-Costs for this (60mi records), and expecting many interactions (loops) in memory to filter, see CPU-Costs.
    So with the parameters you gave to SQL, they start in a very bad way.
    2 After that program will access the MSEG commanded by what was found on First step, also with a huge loading from DB and filtering (another where criteria on MSEG fields, not found on index R), reducing the result set to 76.717 rows.
    3/4 With this, program goes direct to primary key index on MKPF with direct access (optimized access) and follow to access database table MKPF.
    5 At last will "loop" the result sets from MSEG and MKPF, mixing the tuplas generating the final result set.
    Do you want to share your SQL, the parameters you are sending and code which generate it with us?
    Regards, Fernando Da Ró

Maybe you are looking for

  • OSX Lion caused my Macbook to go WACK!

    I have had a few problems with this release. 1. the single most frustrating part is the OSX Lion Sleep COMA! Yes... My computer goes into a coma. After putting it to sleep using my smart corner or if it just falls to sleep and I come back an hour or

  • Clusterware patch for 10.2.0.4

    Will there be any separate patch to upgrade oracle clusterware from 10.2.0.1 to 10.2.0.4.... why because we installed oracle clusterware 10.2.0.1 and Oracle RAC database 10.2.0.1 and upgraded with patch 10.2.0.4.....which upgraded both clusterware an

  • As written in kb404597

    Hi, After installing Adobe Reader 9 the runtime error as written in kb404597 occurs. This technote also gives a solution; don't use a UNC path Anyone an idea how to start Adobe Reader 9 (script/batch) with the following scenario: 1) Before starting A

  • MacBook Pro 10.6.8 still freezing after performing clean install of os.

    Took to local Apple Store and they performed clean install of operating system.  Worked for approximately 10 minutes and back to freezing again.  Can still move cursor but everything else is unresponsive.  Any suggestions would be helpful.  Thanks.

  • Adobe Acrobat XI and Microsoft Expressions 4

    Background: Windows 8.1 box, Adobe Acrobat XI (ver. 11.0.07), Microsoft Web Expressions 4 User has Web Expressions open to the intranet web page access, she's able to use that to make changes, changes are seen reflected on intranet page. However when