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

Similar Messages

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

  • *** Interpreting this explain plan ***

    Hi,
    Please find the explain plan for following: I dont understand why rows = 1 in step 4 and 5 of explain plan?? There are 6 rows corresponding to the condition in join that is satisfied in service def table. Still it shows 1??
    explain plan for SELECT costpools.cost_pool_id, servicedef.service_name,
    costpools.special_calc
    FROM cost_pools costpools, service_definitions servicedef
    WHERE costpools.service_def_id = servicedef.service_def_id
    AND costpools.special_calc = 'Y'
    ORDER BY servicedef.service_name;
    PLAN_TABLE_OUTPUT
    Plan hash value: 3404549211
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 6 | 270 | 15 (7)| 00:00:01 |
    | 1 | SORT ORDER BY | | 6 | 270 | 15 (7)| 00:00:01 |
    | 2 | NESTED LOOPS | | 6 | 270 | 14 (0)| 00:00:01 |
    |* 3 | TABLE ACCESS FULL | COST_POOLS | 6 | 60 | 8 (0)| 00:00:01 |
    | 4 | TABLE ACCESS BY INDEX ROWID| SERVICE_DEFINITIONS | 1 | 35 | 1 (0)| 00:00:0
    |* 5 | INDEX UNIQUE SCAN | SERVICE_DEFINITIONS_PK | 1 | | 0 (0)| 00:00:01
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
    3 - filter("COSTPOOLS"."SPECIAL_CALC"='Y')
    5 - access("COSTPOOLS"."SERVICE_DEF_ID"="SERVICEDEF"."SERVICE_DEF_ID")
    18 rows selected.
    regds,
    s

    I mean how is it executed.....there are 6 rows in the
    service_def table that satisfies the join condition
    right.....so the cardinlity shud be 6 instead of 1
    ..isnt it??That's not the way it works in an explain plan. It works as SomeoneElse said: an index unique scan as the second step inside a nested loop will retrieve 1 row (index unique scan) but 6 times (nested loop). In the plan you'll see a "1". However, if you look at the row source operation in tkprof, it will tell you how many rows were flowing through this step in total, so here it reports 6.
    SQL> create table cost_pools
      2  as
      3   select level cost_pool_id
      4        , 'Y' special_calc
      5        , level service_def_id
      6     from dual
      7  connect by level <= 6
      8  /
    Tabel is aangemaakt.
    SQL> create table service_definitions
      2  as
      3   select 'A' service_name
      4        , level service_def_id
      5     from dual
      6  connect by level <= 10000
      7  /
    Tabel is aangemaakt.
    SQL> alter table service_definitions add constraint service_definitions_pk primary key (service_def_id)
      2  /
    Tabel is gewijzigd.
    SQL> exec dbms_stats.gather_table_stats(user,'cost_pools')
    PL/SQL-procedure is geslaagd.
    SQL> exec dbms_stats.gather_table_stats(user,'service_definitions',cascade=>true)
    PL/SQL-procedure is geslaagd.
    SQL> explain plan
      2  for
      3  SELECT costpools.cost_pool_id, servicedef.service_name,
      4  costpools.special_calc
      5  FROM cost_pools costpools, service_definitions servicedef
      6  WHERE costpools.service_def_id = servicedef.service_def_id
      7  AND costpools.special_calc = 'Y'
      8  ORDER BY servicedef.service_name
      9  /
    Uitleg is gegeven.
    SQL> select * from table(dbms_xplan.display)
      2  /
    PLAN_TABLE_OUTPUT
    | Id  | Operation                     |  Name                   | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT              |                         |     6 |    78 |     5  (20)|
    |   1 |  SORT ORDER BY                |                         |     6 |    78 |     5  (20)|
    |   2 |   NESTED LOOPS                |                         |     6 |    78 |     4   (0)|
    |*  3 |    TABLE ACCESS FULL          | COST_POOLS              |     6 |    48 |     3  (34)|
    |   4 |    TABLE ACCESS BY INDEX ROWID| SERVICE_DEFINITIONS     |     1 |     5 |     2  (50)|
    |*  5 |     INDEX UNIQUE SCAN         | SERVICE_DEFINITIONS_PK  |     1 |       |            |
    Predicate Information (identified by operation id):
       3 - filter("COSTPOOLS"."SPECIAL_CALC"='Y')
       5 - access("COSTPOOLS"."SERVICE_DEF_ID"="SERVICEDEF"."SERVICE_DEF_ID")
    17 rijen zijn geselecteerd.
    SQL> alter session set sql_trace true
      2  /
    Sessie is gewijzigd.
    SQL> SELECT costpools.cost_pool_id, servicedef.service_name,
      2  costpools.special_calc
      3  FROM cost_pools costpools, service_definitions servicedef
      4  WHERE costpools.service_def_id = servicedef.service_def_id
      5  AND costpools.special_calc = 'Y'
      6  ORDER BY servicedef.service_name
      7  /
                              COST_POOL_ID S S
                                         1 A Y
                                         2 A Y
                                         3 A Y
                                         4 A Y
                                         5 A Y
                                         6 A Y
    6 rijen zijn geselecteerd.
    SQL> disconnectAnd now tkprof shows you:
    SELECT costpools.cost_pool_id, servicedef.service_name,
    costpools.special_calc
    FROM cost_pools costpools, service_definitions servicedef
    WHERE costpools.service_def_id = servicedef.service_def_id
    AND costpools.special_calc = 'Y'
    ORDER BY servicedef.service_name
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch        4      0.00       0.00          1         17          0           6
    total        6      0.00       0.00          1         17          0           6
    Misses in library cache during parse: 1
    Optimizer goal: CHOOSE
    Parsing user id: 9833
    Rows     Row Source Operation
          6  SORT ORDER BY
          6   NESTED LOOPS
          6    TABLE ACCESS FULL OBJ#(2702816)
          6    TABLE ACCESS BY INDEX ROWID OBJ#(2702817)
          6     INDEX UNIQUE SCAN OBJ#(2702818) (object id 2702818)
    ********************************************************************************Regards,
    Rob.

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

  • TUNNING A SQL QUERY AND UNSERSTAND EXPLAIN PLAN

    I was trying my handing in tunning sql queries -
    Though I have manged to reduce the cost lil ..creating some index, but have genarated a g8 interesting in tunning - Can some experts ( I know there are lots available :-) ) help me on the approch on "HOW TO TUNE A QUERY"
    moreover I also would like to understand - how to debug a explain plan, - please help ...
    Regards..

    Hi,
    Welcome to this forum...
    I would suggest your to read first the official documentations :
    - The concepts of an Oracle DBMS (this is important to know, because Oracle structures, processes, objects (etc) are the building blocks of your database)
    - SQL reference guide
    - PL/SQL reference guide
    and then at a later stage the Performance and tuning guide:
    You can start there:
    http://download.oracle.com/docs/cd/B14117_01/nav/portal_1.htm
    Once it's done maybe read the Performance and tuning guide:
    http://download.oracle.com/docs/cd/B14117_01/server.101/b10752/toc.htm
    (Chapter 19 explain ... how to interpret the explain plan ..)
    I wish you good chance and be patient: I'm working with Oracle for more that 10 years and I'm still learning! ...
    Rem: The Oracle website is full of interesting articles, and examples, just "search" your special points of interests ..

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

  • 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 in interpreting the output of explain plan

    Hi,
    I have written a query in two different ways and then run an explain plan on both of them. Both these queries give same result. I want to know which one will be more efficient. I am giving the output of explain plan for both the queries:
    The second plan has a lower cost but has much higher consistent gets !!
    Please advise.
    Plan 1:
    Execution Plan
       0      SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=8637 Card= 1 Bytes=10132)
       1    0   SORT (ORDER BY) (Cost=8637 Card=1 Bytes=10132)
       2    1     WINDOW (SORT) (Cost=8637 Card=1 Bytes=10132)
       3    2       COUNT (STOPKEY)
       4    3         VIEW (Cost=8635 Card=1 Bytes=10132)
       5    4           SORT (ORDER BY) (Cost=8635 Card=1 Bytes=862)
       6    5             WINDOW (SORT) (Cost=8635 Card=1 Bytes=862)
       7    6               MAT_VIEW ACCESS (FULL) OF 'PRD_SEARCH_MVW' (MAT_VIEW) (Cost=8633 Card=1 Bytes=862)
    Statistics
            577  recursive calls
              0  db block gets
          39202  consistent gets
          34798  physical reads
              0  redo size
          72348  bytes sent via SQL*Net to client
           4295  bytes received via SQL*Net from client
              9  SQL*Net roundtrips to/from client
             10  sorts (memory)
              0  sorts (disk)
            100  rows processed
    Plan-2
    Execution Plan
       0      SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=982 Card=1 Bytes=10145)
       1    0   SORT (ORDER BY) (Cost=982 Card=1 Bytes=10145)
       2    1     WINDOW (SORT) (Cost=982 Card=1 Bytes=10145)
       3    2       COUNT (STOPKEY)
       4    3         VIEW (Cost=980 Card=1 Bytes=10145)
       5    4           SORT (ORDER BY) (Cost=980 Card=1 Bytes=10132)
       6    5             WINDOW (SORT) (Cost=980 Card=1 Bytes=10132)
       7    6               WINDOW (SORT) (Cost=980 Card=1 Bytes=10132)
       8    7                 VIEW (Cost=977 Card=1 Bytes=10132)
       9    8                   WINDOW (SORT PUSHED RANK) (Cost=977 Card=1 Bytes=889)
      10    9                     NESTED LOOPS (Cost=976 Card=1 Bytes=889)
      11   10                       HASH JOIN (Cost=305 Card=670 Bytes=18090)
      12   11                         HASH JOIN (Cost=23 Card=140 Bytes=2240)
      13   12                           INDEX (FAST FULL SCAN) OF 'GLCAT_GRP_TO_CAT_PK' (INDEX (UNIQUE)) (Cost=2 Card=52 Bytes=364)
      14   12                           MAT_VIEW ACCESS (FULL) OF 'GLCAT_CAT_TO_MCAT' (MAT_VIEW) (Cost=20 Card=1039 Bytes=9351)
      15   11                         INDEX (FAST FULL SCAN) OF 'PCITEM2GLCATMCAT_FK_IDS' (INDEX) (Cost=281 Card=16903 Bytes=185933)
      16   10                       MAT_VIEW ACCESS (BY INDEX ROWID) OF 'PRD_SEARCH_MVW' (MAT_VIEW) (Cost=1 Card=1 Bytes=862)
      17   16                         INDEX (UNIQUE SCAN) OF 'PK_PRD_SEARCH_ID' (INDEX (UNIQUE)) (Cost=0 Card=1)
    Statistics
            481    recursive calls
              2      db block gets
         195742  consistent gets
           7516  physical reads
              0  redo size
          71567  bytes sent via SQL*Net to client
           6629  bytes received via SQL*Net from client
              9  SQL*Net roundtrips to/from client
             15  sorts (memory)
              1  sorts (disk)
            100  rows processedRegards
    Madhup
    Message was edited by:
    Madhup

    Thanks a lot for you input. I am posting both the queries below. My requirements are following:
    1) I have a products table
    2) I have Created grouping hierarchy - Groups, Categories and then Micro-categories - and have setup a separate table for each of them in my database
    3) Then I have mapping tables, i.e. a table that stores group to category mapping, another table that stores category to micro-category mapping.
    4) Products are mapped directly to micro-categories and one product could be mapped to multiple micro-categories.
    5) I have created a materialized view on product and store the mappings as comma separated list of IDs - I have three fields there, on to store comma separated group id, second to store comma separated category ids and third to store the comma separated micro category ids to which the product is mapped.
    Now I want to write a query that will return a specified number of matches from this table based on user defined criterion. There are few other filter cirterion apart from Group/Category and Microcategory. These are Company Name, Country, Type of company etc.
    This query when run on production will be accessed very frequently - I expect the access to be in the tune of around 5-10 times per second.
    There are 50 records in the group table
    There are 500 categories
    There are 20000 micro-categories
    Group to category mapping table has around 1000 records
    Category to microcategory table has around 25000 records
    The product table has around 100,000 products.
    Product to microcategory mapping table has 350000 records
    The product mview has the same number of records as that in products table.
    The first query uses the single materialized view to access data, however, it always does a full table scan and does not use any index.
    When I noticed this in the explain plan, then I tried to write the second query which is using JOINs to arrive at the same output.
    The explain plan now says that it is using Index scans.
    I did a sample run of both the queries on my production system and I had to withdraw both of them as both brought my system to grinding halt within few minutes of going live.
    My system at present receives around 3000 requests per hour during peak load and around 600 requests per hour during off-peak hours.
    And I was testing these queries in Off-peak hours !!
    Here are the two sql queries just for reference - there are several variables plugged in where clause which are the key drivers of the query:
    SQL-1
    SELECT DECODE(:OPT,2,A.SC,(MAX(A.SC) OVER (PARTITION BY A.PRD_SEARCH_COMPANY))) AS SO,
         A.SC,                           A.PRD_SEARCH_ID,
         A.PRD_SEARCH_COMPANY_ID,        A.PRD_SEARCH_COMPANY,            A.PRD_SEARCH_COMPANYID_ENCRYPTED,
         A.PRD_SEARCH_PCID,              A.PRD_SEARCH_URL,                A.PRD_SEARCH_PC_CLNT_HOME,
         A.PRD_SEARCH_CLNT_ENABLED,      A.PRD_SEARCH_CODE,               A.PRD_SEARCH_NAME,
         A.PRD_SEARCH_DESC_SMALL,        A.PRD_SEARCH_DESC_DETAILED,      A.PRD_SEARCH_DESC_HTML,
         A.PRD_SEARCH_IMG_SMALL,         A.PRD_SEARCH_IMG_LARGE,          A.PRD_SEARCH_WEIGHT_ITEM,
         A.PRD_SEARCH_MODIFIEDDATE,      A.PRD_SEARCH_SIZE,               A.PRD_SEARCH_LABEL1,
         A.PRD_SEARCH_LABEL1_VALUE,      A.PRD_SEARCH_LABEL2,             A.PRD_SEARCH_LABEL2_VALUE,
         A.PRD_SEARCH_LABEL3,            A.PRD_SEARCH_LABEL3_VALUE,       A.PRD_SEARCH_LABEL4,
         A.PRD_SEARCH_LABEL4_VALUE,      A.PRD_SEARCH_LABEL5,             A.PRD_SEARCH_LABEL5_VALUE,
         A.PRD_SEARCH_LABEL6,            A.PRD_SEARCH_LABEL6_VALUE,       A.PRD_SEARCH_CAT_ID,
         A.PRD_SEARCH_CAT_NAME,          A.PRD_SEARCH_CAT_FLNAME,         A.PRD_SEARCH_NAVIGATION_TREE,
         A.PRD_SEARCH_NAVIGATION_TREE_ID,A.PRD_SEARCH_CITY,               A.PRD_SEARCH_STATE,
         A.PRD_SEARCH_COUNTRY,           A.PRD_SEARCH_PRICE_SALE,         A.PRD_SEARCH_PC_CLNT_TYPE,
         A.PRD_SEARCH_PC_CLNT_TYPE_DESC,
         A.PRD_SEARCH_COMPANY_PHONE,     A.PRD_SEARCH_COMPANY_MOBILE,     A.PRD_SEARCH_COMPANY_FAX,
         A.PRD_SEARCH_COMPANY_EMAIL,     A.PRD_SEARCH_GLCAT_MCAT_ID_LIST, A.PRD_SEARCH_GLCAT_CAT_ID_LIST,
         A.PRD_SEARCH_GLCAT_GRP_ID_LIST, A.PRD_SEARCH_GL_COUNTRY_ISO,     A.PRD_SEARCH_GLUSR_USR_ID,
         A.PRD_SEARCH_TRUSTSEAL_CODE,    A.PRD_SEARCH_CUSTTYPE_ID,        A.PRD_SEARCH_CUSTTYPE_NAME,
         A.PRD_SEARCH_CUSTTYPE_WEIGHT,   A.PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, A.PRD_SEARCH_CUSTTYPE_RANK,
         A.PRD_SEARCH_PC_ITEM_HOTNEW,    A.RK
         FROM
              (SELECT  /*+ FIRST_ROWS (500) */     DECODE(:S_MODE,2,1,3,to_number(to_char(PRD_SEARCH_MODIFIEDDATE,'yyyymmdd')),1) AS SC,
              PRD_SEARCH_ID,
              PRD_SEARCH_COMPANY_ID,        PRD_SEARCH_COMPANY,            PRD_SEARCH_COMPANYID_ENCRYPTED,
              PRD_SEARCH_PCID,              PRD_SEARCH_URL,                PRD_SEARCH_PC_CLNT_HOME,
              PRD_SEARCH_CLNT_ENABLED,      PRD_SEARCH_CODE,               PRD_SEARCH_NAME,
              PRD_SEARCH_DESC_SMALL,        PRD_SEARCH_DESC_DETAILED,      PRD_SEARCH_DESC_HTML,
              PRD_SEARCH_IMG_SMALL,         PRD_SEARCH_IMG_LARGE,          PRD_SEARCH_WEIGHT_ITEM,
              PRD_SEARCH_MODIFIEDDATE,      PRD_SEARCH_SIZE,               PRD_SEARCH_LABEL1,
              PRD_SEARCH_LABEL1_VALUE,      PRD_SEARCH_LABEL2,             PRD_SEARCH_LABEL2_VALUE,
              PRD_SEARCH_LABEL3,            PRD_SEARCH_LABEL3_VALUE,       PRD_SEARCH_LABEL4,
              PRD_SEARCH_LABEL4_VALUE,      PRD_SEARCH_LABEL5,             PRD_SEARCH_LABEL5_VALUE,
              PRD_SEARCH_LABEL6,            PRD_SEARCH_LABEL6_VALUE,       PRD_SEARCH_CAT_ID,
              PRD_SEARCH_CAT_NAME,          PRD_SEARCH_CAT_FLNAME,         PRD_SEARCH_NAVIGATION_TREE,
              PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY,               PRD_SEARCH_STATE,
              PRD_SEARCH_COUNTRY,           PRD_SEARCH_PRICE_SALE,         PRD_SEARCH_PC_CLNT_TYPE,
              PRD_SEARCH_PC_CLNT_TYPE_DESC,
              PRD_SEARCH_COMPANY_PHONE,     PRD_SEARCH_COMPANY_MOBILE,     PRD_SEARCH_COMPANY_FAX,
              PRD_SEARCH_COMPANY_EMAIL,     PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
              PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO,     PRD_SEARCH_GLUSR_USR_ID,
              PRD_SEARCH_TRUSTSEAL_CODE,    PRD_SEARCH_CUSTTYPE_ID,        PRD_SEARCH_CUSTTYPE_NAME,
              PRD_SEARCH_CUSTTYPE_WEIGHT,   PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
              PRD_SEARCH_PC_ITEM_HOTNEW,
              ROW_NUMBER() OVER (PARTITION BY PRD_SEARCH_COMPANY_ID
                                  ORDER BY DECODE(:S_MODE,2,1,3,to_number(to_char(PRD_SEARCH_MODIFIEDDATE,'yyyymmdd')),1) DESC) AS RK
              FROM      PRD_SEARCH
              WHERE     DECODE(:GRP_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_GRP_ID_LIST,' ','')||',',:MYGRP_ID_STR)) > 0
              AND       DECODE(:CAT_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_CAT_ID_LIST,' ','')||',',:MYCAT_ID_STR)) > 0
              AND       DECODE(:MCAT_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_MCAT_ID_LIST,' ','')||',',:MYMCAT_ID_STR)) > 0
              AND       DECODE(:ITEM_ID_STR,NULL,1,REGEXP_INSTR(','||PRD_SEARCH_ID||',',:MYITEM_ID_STR)) > 0
              AND       DECODE(:COUNTRY_ISO,NULL,1,REGEXP_INSTR(','||PRD_SEARCH_GL_COUNTRY_ISO||',',:COUNTRY_ISO)) > 0
              AND       DECODE(nvl(NULL,0),0,1,PRD_SEARCH_COMPANY_ID) = DECODE(nvl(NULL,0),0,1,NULL)
              AND       DECODE(nvl(NULL,0),0,1,PRD_SEARCH_GLUSR_USR_ID) = DECODE(nvl(NULL,0),0,1,NULL)
              AND       PRD_SEARCH_CLNT_ENABLED >= nvl(:LIST_TYPE,0)
              AND       NVL(Length(PRD_SEARCH_TRUSTSEAL_CODE),0) >= :TSONLY
              ORDER BY SC DESC, PRD_SEARCH_CUSTTYPE_WEIGHT ASC, DBMS_RANDOM.RANDOM
              )  A
    WHERE A.RK <= :MY_PRD_PER_COMP
    AND   ROWNUM <= :MYMAXREC
    ORDER BY SO DESC, DECODE(:OPT,2,'1',A.PRD_SEARCH_COMPANY), A.RK ASC, DBMS_RANDOM.RANDOM
    SQL-2
         SELECT
              DECODE(:OPT,2,SC,(MAX(SC) OVER (PARTITION BY PRD_SEARCH_COMPANY))) AS SO,
              SC,                           PRD_SEARCH_ID,
              PRD_SEARCH_COMPANY_ID,        PRD_SEARCH_COMPANY,            PRD_SEARCH_COMPANYID_ENCRYPTED,
              PRD_SEARCH_PCID,              PRD_SEARCH_URL,                PRD_SEARCH_PC_CLNT_HOME,
              PRD_SEARCH_CLNT_ENABLED,      PRD_SEARCH_CODE,               PRD_SEARCH_NAME,
              PRD_SEARCH_DESC_SMALL,        PRD_SEARCH_DESC_DETAILED,      PRD_SEARCH_DESC_HTML,
              PRD_SEARCH_IMG_SMALL,         PRD_SEARCH_IMG_LARGE,          PRD_SEARCH_WEIGHT_ITEM,
              PRD_SEARCH_MODIFIEDDATE,      PRD_SEARCH_SIZE,               PRD_SEARCH_LABEL1,
              PRD_SEARCH_LABEL1_VALUE,      PRD_SEARCH_LABEL2,             PRD_SEARCH_LABEL2_VALUE,
              PRD_SEARCH_LABEL3,            PRD_SEARCH_LABEL3_VALUE,       PRD_SEARCH_LABEL4,
              PRD_SEARCH_LABEL4_VALUE,      PRD_SEARCH_LABEL5,             PRD_SEARCH_LABEL5_VALUE,
              PRD_SEARCH_LABEL6,            PRD_SEARCH_LABEL6_VALUE,       PRD_SEARCH_CAT_ID,
              PRD_SEARCH_CAT_NAME,          PRD_SEARCH_CAT_FLNAME,         PRD_SEARCH_NAVIGATION_TREE,
              PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY,               PRD_SEARCH_STATE,
              PRD_SEARCH_COUNTRY,           PRD_SEARCH_PRICE_SALE,         PRD_SEARCH_PC_CLNT_TYPE,
              PRD_SEARCH_PC_CLNT_TYPE_DESC,
              PRD_SEARCH_COMPANY_PHONE,     PRD_SEARCH_COMPANY_MOBILE,     PRD_SEARCH_COMPANY_FAX,
              PRD_SEARCH_COMPANY_EMAIL,     PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
              PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO,     PRD_SEARCH_GLUSR_USR_ID,
              PRD_SEARCH_TRUSTSEAL_CODE,    PRD_SEARCH_CUSTTYPE_ID,        PRD_SEARCH_CUSTTYPE_NAME,
              PRD_SEARCH_CUSTTYPE_WEIGHT,   PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
              PRD_SEARCH_PC_ITEM_HOTNEW,    RK
         FROM
                   SELECT
                        /*+ FIRST_ROWS (500) */ DECODE(:OPT,2,SC,(MAX(SC) OVER (PARTITION BY PRD_SEARCH_COMPANY))) AS SO,
                        SC,PRD_SEARCH_ID,
                        PRD_SEARCH_COMPANY_ID,        PRD_SEARCH_COMPANY,            PRD_SEARCH_COMPANYID_ENCRYPTED,
                        PRD_SEARCH_PCID,              PRD_SEARCH_URL,                PRD_SEARCH_PC_CLNT_HOME,
                        PRD_SEARCH_CLNT_ENABLED,      PRD_SEARCH_CODE,               PRD_SEARCH_NAME,
                        PRD_SEARCH_DESC_SMALL,        PRD_SEARCH_DESC_DETAILED,      PRD_SEARCH_DESC_HTML,
                        PRD_SEARCH_IMG_SMALL,         PRD_SEARCH_IMG_LARGE,          PRD_SEARCH_WEIGHT_ITEM,
                        PRD_SEARCH_MODIFIEDDATE,      PRD_SEARCH_SIZE,               PRD_SEARCH_LABEL1,
                        PRD_SEARCH_LABEL1_VALUE,      PRD_SEARCH_LABEL2,             PRD_SEARCH_LABEL2_VALUE,
                        PRD_SEARCH_LABEL3,            PRD_SEARCH_LABEL3_VALUE,       PRD_SEARCH_LABEL4,
                        PRD_SEARCH_LABEL4_VALUE,      PRD_SEARCH_LABEL5,             PRD_SEARCH_LABEL5_VALUE,
                        PRD_SEARCH_LABEL6,            PRD_SEARCH_LABEL6_VALUE,       PRD_SEARCH_CAT_ID,
                        PRD_SEARCH_CAT_NAME,          PRD_SEARCH_CAT_FLNAME,         PRD_SEARCH_NAVIGATION_TREE,
                        PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY,               PRD_SEARCH_STATE,
                        PRD_SEARCH_COUNTRY,           PRD_SEARCH_PRICE_SALE,         PRD_SEARCH_PC_CLNT_TYPE,
                        PRD_SEARCH_PC_CLNT_TYPE_DESC,
                        PRD_SEARCH_COMPANY_PHONE,     PRD_SEARCH_COMPANY_MOBILE,     PRD_SEARCH_COMPANY_FAX,
                        PRD_SEARCH_COMPANY_EMAIL,     PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
                        PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO,     PRD_SEARCH_GLUSR_USR_ID,
                        PRD_SEARCH_TRUSTSEAL_CODE,    PRD_SEARCH_CUSTTYPE_ID,        PRD_SEARCH_CUSTTYPE_NAME,
                        PRD_SEARCH_CUSTTYPE_WEIGHT,   PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
                        PRD_SEARCH_PC_ITEM_HOTNEW,
                        ROW_NUMBER() OVER (PARTITION BY PRD_SEARCH_COMPANY_ID
                                  ORDER BY DECODE(:S_MODE,2,1,3,TO_NUMBER(TO_CHAR(PRD_SEARCH_MODIFIEDDATE,'YYYYMMDD')),1) DESC) AS RK
                   FROM
                             SELECT
                                  DECODE(:S_MODE,2,1,3,TO_NUMBER(TO_CHAR(PRD_SEARCH_MODIFIEDDATE,'YYYYMMDD')),1) AS SC,
                                  PRD_SEARCH_ID,
                                  PRD_SEARCH_COMPANY_ID,        PRD_SEARCH_COMPANY,            PRD_SEARCH_COMPANYID_ENCRYPTED,
                                  PRD_SEARCH_PCID,              PRD_SEARCH_URL,                PRD_SEARCH_PC_CLNT_HOME,
                                  PRD_SEARCH_CLNT_ENABLED,      PRD_SEARCH_CODE,               PRD_SEARCH_NAME,
                                  PRD_SEARCH_DESC_SMALL,        PRD_SEARCH_DESC_DETAILED,      PRD_SEARCH_DESC_HTML,
                                  PRD_SEARCH_IMG_SMALL,         PRD_SEARCH_IMG_LARGE,          PRD_SEARCH_WEIGHT_ITEM,
                                  PRD_SEARCH_MODIFIEDDATE,      PRD_SEARCH_SIZE,               PRD_SEARCH_LABEL1,
                                  PRD_SEARCH_LABEL1_VALUE,      PRD_SEARCH_LABEL2,             PRD_SEARCH_LABEL2_VALUE,
                                  PRD_SEARCH_LABEL3,            PRD_SEARCH_LABEL3_VALUE,       PRD_SEARCH_LABEL4,
                                  PRD_SEARCH_LABEL4_VALUE,      PRD_SEARCH_LABEL5,             PRD_SEARCH_LABEL5_VALUE,
                                  PRD_SEARCH_LABEL6,            PRD_SEARCH_LABEL6_VALUE,       PRD_SEARCH_CAT_ID,
                                  PRD_SEARCH_CAT_NAME,          PRD_SEARCH_CAT_FLNAME,         PRD_SEARCH_NAVIGATION_TREE,
                                  PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY,               PRD_SEARCH_STATE,
                                  PRD_SEARCH_COUNTRY,           PRD_SEARCH_PRICE_SALE,         PRD_SEARCH_PC_CLNT_TYPE,
                                  PRD_SEARCH_PC_CLNT_TYPE_DESC,
                                  PRD_SEARCH_COMPANY_PHONE,     PRD_SEARCH_COMPANY_MOBILE,     PRD_SEARCH_COMPANY_FAX,
                                  PRD_SEARCH_COMPANY_EMAIL,     PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
                                  PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO,     PRD_SEARCH_GLUSR_USR_ID,
                                  PRD_SEARCH_TRUSTSEAL_CODE,    PRD_SEARCH_CUSTTYPE_ID,        PRD_SEARCH_CUSTTYPE_NAME,
                                  PRD_SEARCH_CUSTTYPE_WEIGHT,   PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
                                  PRD_SEARCH_PC_ITEM_HOTNEW,
                                  ROW_NUMBER() OVER (PARTITION BY P.PRD_SEARCH_ID ORDER BY P.PRD_SEARCH_ID) RK1
                             FROM
                                  GLCAT_GRP_TO_CAT G2C, GLCAT_CAT_TO_MCAT C2M, PC_ITEM_TO_GLCAT_MCAT M, PRD_SEARCH P
                             WHERE
                                  G2C.FK_GLCAT_CAT_ID = C2M.FK_GLCAT_CAT_ID
                                  AND C2M.FK_GLCAT_MCAT_ID = M.FK_GLCAT_MCAT_ID
                                  AND M.FK_PC_ITEM_ID = P.PRD_SEARCH_ID
                                  AND DECODE(:MCAT_ID_STR, NULL, 1, INSTR(','||:MCAT_ID_STR||',',','||M.FK_GLCAT_MCAT_ID||',',1))> 0
                                  AND DECODE(:CAT_ID_STR, NULL, 1, INSTR(','||:CAT_ID_STR||',',','||C2M.FK_GLCAT_CAT_ID||',',1)) > 0
                                  AND DECODE(:GRP_ID_STR, NULL, 1, INSTR(','||:GRP_ID_STR||',',','||G2C.FK_GLCAT_GRP_ID||',',1)) > 0
                                  AND DECODE(:ITEM_ID_STR,NULL,1,INSTR(','||:ITEM_ID_STR||',' , ','||P.PRD_SEARCH_ID||',')) > 0
                                  AND DECODE(:COUNTRY_ISO,NULL,1,INSTR(','||:COUNTRY_ISO||',', ','||P.PRD_SEARCH_GL_COUNTRY_ISO||',')) > 0
                                  AND DECODE(NVL(:COMPANY_ID,0),0,1,P.PRD_SEARCH_COMPANY_ID) = DECODE(NVL(:COMPANY_ID,0),0,1,:COMPANY_ID)
                                  AND DECODE(NVL(:GLUSR_ID,0),0,1,P.PRD_SEARCH_GLUSR_USR_ID) = DECODE(NVL(:GLUSR_ID,0),0,1,:GLUSR_ID)
                                  AND P.PRD_SEARCH_CLNT_ENABLED >= NVL(:LIST_TYPE,0)
                                  AND NVL(LENGTH(P.PRD_SEARCH_TRUSTSEAL_CODE),0) >= :TSONLY
                   WHERE RK1=1
                   ORDER BY SC DESC, PRD_SEARCH_CUSTTYPE_WEIGHT ASC, DBMS_RANDOM.RANDOM
              ) A
         WHERE A.RK <= :MY_PRD_PER_COMP
         AND   ROWNUM <= :MYMAXREC
         ORDER BY A.SO DESC, DECODE(:OPT,2,'1', A.PRD_SEARCH_COMPANY), A.RK ASC, DBMS_RANDOM.RANDOMRegards
    Madhup

  • Explain Plan query

    I just changed the hint to pick different indexes inside the same SQL and they have significant different performance. SQL1 is much faster than SQL2 and the explain plain is very different. I found that there is some values like :Q1003, :Q1004 and :Q1005 under Object Code in the explain plan of SQL1. May I know how to interpret this?
    Thanks.
    Edited by: 843672 on Mar 11, 2011 3:42 AM

    Welcome to the forum.
    Before you even think of posting another 'question', first read:
    http://tkyte.blogspot.com/2005/06/how-to-ask-questions.html
    and secondly, when it comes to tuning requests, read:
    When your query takes too long ...
    HOW TO: Post a SQL statement tuning request - template posting
    and there's also a FAQ and a SQL and PL/SQL FAQ....
    http://forums.oracle.com/forums/ann.jspa?annID=1535

  • Understand an explain plan

    Hi,
    following is the explain plan for my query :
    Plan Table
    | Operation                 |  Name              |  Rows | Bytes|  Cost  | Pstart| Pstop |
    | SELECT STATEMENT          |                    |     1 |  139 |    464 |       |       |
    |  SORT GROUP BY            |                    |     1 |  139 |    464 |       |       |
    |   NESTED LOOPS            |                    |     1 |  139 |    453 |       |       |
    |    HASH JOIN              |                    |   352 |   35K|    277 |       |       |
    |     NESTED LOOPS          |                    |   105 |    7K|     54 |       |       |
    |      TABLE ACCESS BY INDEX|PS_CE_ITEMVAR_TMP   |   101 |    5K|     53 |       |       |
    |       INDEX RANGE SCAN    |PS_C_ITEMVAR_TMP    |   101 |      |      5 |       |       |
    |      INDEX UNIQUE SCAN    |PS_ITEMS_INV        |    14K|  244K|        |       |       |
    |     TABLE ACCESS FULL     |PS_OUTPUT_LIST      |    47K|    1M|    222 |       |       |
    Plan Table
    |    TABLE ACCESS BY INDEX R|PS_SF_PRDNID_HEADR  |    31K|    1M|      1 |       |       |
    |     INDEX UNIQUE SCAN     |PS_SF_PRDNID_HEADR  |    31K|      |        |       |       |
    ------------------------------------------------------------------------------------------How to understand it ? How to interpret it ?
    Does this explain plan suggest you any tuning or any idea ?
    Many thanks.

    Can you check if you can avoid full table scan of this table - PS_OUTPUT_LIST
    How to understand it ? How to interpret it ?Here is the rule.
    1) First goto the inner most line. That will be the first one to get executed/accessed
    Note : If two are two lines that are the same innermost level, then the one that is above it will get accessed first.
    Here is the order for your case in sequence
    1) INDEX RANGE SCAN |PS_C_ITEMVAR_TMP
    2) TABLE ACCESS BY INDEX|PS_CE_ITEMVAR_TMP (a)
    3) INDEX UNIQUE SCAN - PS_ITEMS_INV (b)
    4) a and b will be joined to form a rowset - (c)
    5) TABLE ACCESS FULL |PS_OUTPUT_LIST - (d)
    6) c and d will have NESTED LOOPS ..
    So on...
    Please read the 9i or 10g Performance Tuning guide - that has the same explanation in the initial chapters
    Message was edited by:
    Srinivas.R

  • Explain plan going in Billions

    Dear All,
    We are having a huge table of data and when I am running explain plan for the table I am getting the below plan from ORACLE.
    | Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
    | 0 | SELECT STATEMENT | | 4149 | 129K| 1692 | | |
    | 1 | SORT GROUP BY NOSORT | | 4149 | 129K| 1692 | | |
    | 2 | VIEW | | 4149 | 129K| 1692 | | |
    | 3 | SORT GROUP BY | | 4149 | 717K| 1692 | | |
    | 4 | FILTER | | | | | | |
    | 5 | HASH JOIN | | 4149 | 717K| 1691 | | |
    | 6 | TABLE ACCESS FULL | R_CFG_CATEGORY_MAS | 103 | 4429 | 3 | | |
    | 7 | HASH JOIN | | 4149 | 542K| 1687 | | |
    | 8 | PARTITION RANGE ITERATOR | | 4149 | 287K| 21687 | KEY | KEY |
    | 9 | PARTITION HASH SINGLE | | 4149 | 287K| 21687 | KEY | KEY |
    | 10 | TABLE ACCESS FULL | R_CFG_WH_EXCEP | 4149 | 287K| 21687 | | |
    | 11 | MERGE JOIN CARTESIAN | | 2105K| 126M| *18E*| | |
    | 12 | VIEW | | 475 | 10925 | 3 | | |
    | 13 | CONNECT BY WITH FILTERING | | | | | | |
    | 14 | TABLE ACCESS BY INDEX ROWID| R_CFG_CAT_HIERARCHY_MAS | | | | | |
    | 15 | NESTED LOOPS | | 19 | 247 | 3 | | |
    | 16 | TABLE ACCESS FULL | R_CFG_CAT_HIERARCHY_MAS | 19 | 171 | 3 | | |
    | 17 | INDEX UNIQUE SCAN | PK_RCCHM_CAT_REGID_PK | 1 | 4 | 0 | | |
    | 18 | HASH JOIN | | | | | | |
    | 19 | CONNECT BY PUMP | | | | | | |
    | 20 | TABLE ACCESS FULL | R_CFG_CAT_HIERARCHY_MAS | 475 | 5225 | 3 | | |
    | 21 | TABLE ACCESS FULL | R_CFG_CAT_HIERARCHY_MAS | 475 | 5225 | 3 | | |
    | 22 | BUFFER SORT | | 4432 | 173K| *18E*| | |
    | 23 | TABLE ACCESS BY INDEX ROWID | R_DEVICE_INFO | 4432 | 173K| *18E*| | |
    | 24 | BITMAP CONVERSION TO ROWIDS| | | | | | |
    | 25 | BITMAP INDEX SINGLE VALUE | R_DEVICE_INFO_CPYKEY | | | | | |
    Note
    - 'PLAN_TABLE' is old version
    I can see cost in 18E which is huge and ridiculous.
    I can explain points that I noted on this table.
    This table is having more than 1 BILLIION RECORDS AND I am querying for a user which has got 5 MILLION RECORDS.
    This table is properly partitioned and is having proper indexes.
    We got some BITMAP indexes on this table also.
    This table has got proper partitioned indexes also. (But the indexes and the table are in the same tablespace).
    Can Anyone give me some sugessitions on how to reduce the overall cost.
    Appreciate your response on this one.
    Thanks,
    Madhu K.

    569725 wrote:
    I can see cost in 18E which is huge and ridiculous.For a cartesian merge join... Cartesian joins are notoriously expensive.
    This table is having more than 1 BILLIION RECORDS AND I am querying for a user which has got 5 MILLION RECORDS.Does not matter. The number of rows (note we store rows in tables, not records) does not matter. It is about how much I/O is needed to process that amount of data.
    And this is what invariably we design for.. using relational design, using indexes, using partitioning, using clustering, etc. All these are techniques to reduce I/O. From eliminating duplication of data to providing optimal I/O paths to the data.
    A real world example:
    SQL> set timing on
    SQL> select count(*) from daily_xxxxx;
      COUNT(*)
    2160339906
    Elapsed: 00:00:10.09
    SQL>
    SQL> select count(*) from all_objects;
      COUNT(*)
         51255
    Elapsed: 00:01:43.60So despite "+processing+" over 2 billion rows, the count is significantly faster than the count of the very much smaller ALL_OBJECTS view.
    Why? Because it took less I/O to count those 2 billion rows (using a single index) than the nearly 52 thousand objects in the data dictionary (using several indexes and tables).
    The rules that governs performance do not change with the number of rows in a table. The same rules and principles apply. What does change is the "+error margin+" - you are going to see a performance problem quite a lot sooner on a large table than a very small table. You may not notice that a 1ms overhead per row is a performance problem on a 100 row table. You will definitely notice it on a million row table.
    So forget about the number of rows in these tables. Make sure that the SQL is designed logically correctly. Make sure that the table/db design provides optimal I/O paths for that SQL.
    And catersian merge joins, nested loops with full table scans and so on.. that points to both these as being potential problems. SQL designed incorrectly (like forgetting join criteria). Table design lacking (requiring nested loop full table scans as oppose to index range scans or hash joins).
    Oh yeah - and as already mentioned, forget the cost that the execution plan shows. Unless you know what unit that cost is expressed in and how to interpret it?

  • Query with Explain Plan

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

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

  • Explain Plan for a SQL

    Hi
    I have done an explain for one of my sql and i got the result as follows
    SELECT STATEMENT Cost = 502
    SORT AGGREGATE
    HASH JOIN
    NESTED LOOPS
    HASH JOIN
    TABLE ACCESS FULL CMC_NWPE_RELATION
    HASH JOIN
    TABLE ACCESS FULL CMC_NWST_NET_SET
    NESTED LOOPS
    TABLE ACCESS FULL CMC_NWPR_RELATION
    INDEX UNIQUE SCAN SYS_C006513
    INDEX UNIQUE SCAN SYS_C006316
    TABLE ACCESS FULL CMC_MEPR_PRIM_PROV
    I need to know whether i have gone wrong with any of the joins in the sql. For the matter of fact I need to interpret the result of the explain plan for my sql.
    Thanks in advance
    Chandra Sekhar

    Hi
    First of all u haven't send the complete explanation in the plan table. As far i got from your result ur accesing the ful table scan CMC_NWPE_RELATION ,CMC_NWST_NET_SET , CMC_NWPR_RELATION & one more.
    check in your auery why these table are accesing full when the data in this table will volumonuous ur system this query will become very slow as it will have to acces nosof rowsin table 1*nosof rowsin table 2*nosof rowsin table 3*nosof rowsin table 4 so u create the index in those tables and index should be made on the columns which r used in ur where clause of the query
    Amit

  • Autotrace explain plan

    Hi
    i like to know how can i understand the output of the autotrace ..
    my current sql explain plan is
    Execution Plan
    Plan hash value: 2038802176
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 9 | 1026 | 332 (3)| 00:00:04 |
    | 1 | SORT ORDER BY | | 9 | 1026 | 332 (3)| 00:00:04 |
    | 2 | HASH UNIQUE | | 9 | 1026 | 331 (3)| 00:00:04 |
    | 3 | NESTED LOOPS | | | | | |
    | 4 | NESTED LOOPS | | 9 | 1026 | 330 (2)| 00:00:04 |
    |* 5 | TABLE ACCESS FULL | EATTEND_STUDENT_ATTENDANCE | 9 | 144 | 294 (3)|
    |* 6 | INDEX RANGE SCAN | PERF_EATTEND_STUDENT_INFO_N99 | 7 | | 2 (0)| 0
    |* 7 | TABLE ACCESS BY INDEX ROWID| EATTEND_STUDENT_INFO | 1 | 98 | 4 (0)| 0
    how will i decide where is the performance issue ???
    thanks

    Don't think you have any issues here, given the small number of rows you're query returns.
    You can find useful information regariding interpreting execution plans by exploring these links:
    http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm#i16971
    http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:111012348061
    http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:231814117467
    and do some searches on those sites yourself
    Also, post your execution plan between the {noformat}{noformat} tag, so it'll stay formatted.
    For example, when you type:
    {noformat}select *
    from dual{noformat}
    it will appear as:select *
    from dualwhen you post it on this forum.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • About explain plan

    Hello ALL,
    I have the following explain plan, can any body explain the meaning of this explain plan
    SELECT * FROM
    2 TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE','111'));
    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost |
    | 0 | SELECT STATEMENT | | 401 | 25263 | | 751K|
    | 1 | MERGE JOIN SEMI | | 401 | 25263 | | 751K|
    | 2 | SORT JOIN | | 17M| 820M| 2108M| 75297 |
    | 3 | TABLE ACCESS FULL | TABLE1 | 17M| 820M| | 3520 |
    |* 4 | SORT UNIQUE | | 275M| 3412M| 10G| 676K|
    | 5 | VIEW | VW_NSO_1 | 275M| 3412M| | 3538 |
    |* 6 | HASH JOIN | | 275M| 7874M| | 3538 |
    |* 7 | TABLE ACCESS FULL| TABLE2 | 16 | 128 | | 2 |
    |* 8 | TABLE ACCESS FULL| TABLE1 | 17M| 360M| | 3520 |
    Predicate Information (identified by operation id):
    4 - access("TABLE1"."POSITION"="VW_NSO_1"."$nso_col_1")
    filter("TABLE1"."POSITION"="VW_NSO_1"."$nso_col_1")
    6 - access("TABLE2"."VERSION_NO"="TABLE1"."VERSION_NO")
    7 - filter("TABLE2"."STATIC_UPD_FLAG"='N')
    8 - filter("TABLE1"."DATETIME_INSERTED">TO_DATE('0004-01-01 00:00:00',
    'yyyy-mm-dd hh24:mi:ss'))
    Note: cpu costing is off
    26 rows selected.
    SQL>

    There is a section in the manual on interpreting the output of explain plan http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96533/ex_plan.htm#16972 Tom Kyte also discusses interpreting the plan http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:231814117467#7344298017927 (page down about halfway where he starts his book excerpt).
    Rows, bytes, and temp space are the cost-based optimizer's guess about the number of rows, bytes, and temp space that will be touched (or consumed) by the operation. The cost is an internal number that has no significance to you when you're reading an explain plan-- it does have some significance when you are examining an event 10046 trace.
    Justin
    Distributed Database Consulting, Inc.
    http://www.ddbcinc.com/askDDBC

Maybe you are looking for

  • .java files appear double spaced in Jdeveloper IDE.

    After checking for updates and not finding what I was looking for, all .java files appear double spaced in the Code Editor. I can't find project property that seems to control this. The files appear fine when opened with other editors.

  • Simple recorder for mac

    g'day all, I am wondering if there is a simple recording app out there that will just reside in the menu bar (not the dock). when i press a shortcut key, i want it to record through the microphone and when i let go of the button to save it in a folde

  • Xcelsius and SQL Server 2008 Reporting Services

    I am totally and utterly p1$$3d off and surely I cannot be the only person to be using a similar setup i.e. Xcelsius along with SQL Server 2008 Reporting Services. I have installed and tried to get working the XRS gateway and get connectivity to Repo

  • We need to implement EP Solution for Supplier Portal

    Hello All,      I'm working on BSP's and Portal since 1 Year. The Portal Implementation is already done before I started working on it. Now my scenario is as folows : We need to implement EP Solution for Supplier Portal . For this we want to know wha

  • Class redefinition exception

    While using the class redefinition feature (redefineClass) of JRockit, I am getting an exception (part stacktrace below) com.bea.jvm.ClassRedefinitionException: Class redefinition failed! at jrockit.management.jvm.ClassLibraryImpl.redefineClass0(Ljav