Query Explain Plan Help

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

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

Similar Messages

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

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

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

  • Strange query / explain plan

    (I posted this in the Oracle Text forum, but I think it's as appropriate here.)
    Consider the following queries:
    :the_filter := 'FILE';
    (1)
    SELECT COUNT(*)
    FROM FOO
    WHERE CONTAINS(search_col,:the_filter) > 0;
    (2)
    SELECT COUNT(*)
    FROM FOO
    WHERE 'FILE' IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    (3)
    SELECT COUNT(*)
    FROM FOO
    WHERE :the_filter IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    (1) and (2) use the text index and run normally, but (3) does a full table scan, but I don't understand why.
    The reason behind my using a query of the form (3) is to say 'keep the record if the filter is null or the record contains the filter'. I'm using the filter as a switch, and (3) is actually a simplified form of a complex query with several tables and filters. How can I do this without the query using a full table scan?
    Below is the script and a record of the full session:
    SET ECHO ON;
    SET TIMING ON;
    DROP TABLE FOO;
    CREATE TABLE FOO (search_col VARCHAR2(100));
    -- Loads of dummy data
    INSERT INTO FOO (search_col) SELECT OBJECT_NAME || ' ' || OBJECT_TYPE
    FROM ALL_OBJECTS WHERE ROWNUM <= 20000;
    COMMIT;
    CREATE INDEX I1 ON FOO(search_col) INDEXTYPE IS CTXSYS.CONTEXT
    PARAMETERS(' section group ctxsys.html_section_group');
    variable the_filter varchar2(100);
    begin
    :the_filter := 'FILE';
    end;
    SET AUTOTRACE ON EXPLAIN;
    SELECT COUNT(*)
    FROM FOO
    WHERE CONTAINS(search_col,:the_filter) > 0;
    SELECT COUNT(*)
    FROM FOO
    WHERE 'FILE' IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    SELECT COUNT(*)
    FROM FOO
    WHERE :the_filter IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.6.0 - Production
    SQL*Plus: Release 10.2.0.1.0 - Production on Tue Nov 21 11:21:22 2006
    Copyright (c) 1982, 2005, Oracle. All rights reserved.
    Connected to:
    Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.6.0 - Production
    SQL> SET TIMING ON;
    SQL> DROP TABLE FOO;
    Table dropped.
    Elapsed: 00:00:00.73
    SQL> CREATE TABLE FOO (search_col VARCHAR2(100));
    Table created.
    Elapsed: 00:00:00.03
    SQL> -- Loads of dummy data
    SQL> INSERT INTO FOO (search_col) SELECT OBJECT_NAME || ' ' || OBJECT_TYPE
    2 FROM ALL_OBJECTS WHERE ROWNUM <= 20000;
    20000 rows created.
    Elapsed: 00:00:01.92
    SQL> COMMIT;
    Commit complete.
    Elapsed: 00:00:00.01
    SQL> CREATE INDEX I1 ON FOO(search_col) INDEXTYPE IS CTXSYS.CONTEXT
    2 PARAMETERS(' section group ctxsys.html_section_group');
    Index created.
    Elapsed: 00:00:10.76
    SQL> variable the_filter varchar2(100);
    SQL> begin
    2 :the_filter := 'FILE';
    3 end;
    4 /
    PL/SQL procedure successfully completed.
    Elapsed: 00:00:00.00
    SQL> SET AUTOTRACE ON EXPLAIN;
    SQL> SELECT COUNT(*)
    2 FROM FOO
    3 WHERE CONTAINS(search_col,:the_filter) > 0;
    COUNT(*)
    29
    Elapsed: 00:00:00.07
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=59)
    1 0 SORT (AGGREGATE)
    2 1 DOMAIN INDEX OF 'I1' (Cost=0 Card=1 Bytes=59)
    SQL> SELECT COUNT(*)
    2 FROM FOO
    3 WHERE 'FILE' IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    COUNT(*)
    29
    Elapsed: 00:00:00.08
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=59)
    1 0 SORT (AGGREGATE)
    2 1 DOMAIN INDEX OF 'I1' (Cost=0 Card=1 Bytes=59)
    SQL> SELECT COUNT(*)
    2 FROM FOO
    3 WHERE :the_filter IS NULL OR CONTAINS(search_col,:the_filter) > 0;
    COUNT(*)
    29
    Elapsed: 00:00:04.06
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=34482 Card=1 Bytes=5
    9)
    1 0 SORT (AGGREGATE)
    2 1 TABLE ACCESS (FULL) OF 'FOO' (Cost=34482 Card=453 Bytes=
    26727)

    Nothing is really strange when you are attempting to integrate with legacy systems! =)
    If no numerical processing is done why should numerical values be stored as numbers?

  • Query Performance COST - HELP

    Hello Experts,
    Please help me how the table "digital_compatibility" be modified for faster performance?
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
    PL/SQL Release 10.2.0.1.0 - Production
    CORE     10.2.0.1.0     Production
    TNS for IBM/AIX RISC System/6000: Version 10.2.0.1.0 - Productio
    NLSRTL Version 10.2.0.1.0 - Production
    Count of records for the tables:-
    SELECT count(*) FROM DEVICE_TYPE; --421
    SELECT count(*) FROM DIGITAL_COMPATIBILITY; --227757
    CREATE TABLE  DEVICE_TYPE
         DEVICE_TYPE_ID          NUMBER(38,0),
         DEVICE_TYPE_MAKE        VARCHAR2(256 BYTE),
         DEVICE_TYPE_MODEL       VARCHAR2(256 BYTE),
         DEVICE_DISPLAY_NAME     VARCHAR2(256 BYTE),
         PARTNER_DEVICE_TYPE     VARCHAR2(256 BYTE),
         DEVICE_IMAGE_URL        VARCHAR2(256 BYTE),
         FOH_BUTTON_NAME         VARCHAR2(256 BYTE),
         FOH_ACTIVE_FLAG         CHAR(1 BYTE),
         BB_RETAIL_FLAG          CHAR(1 BYTE),
         DISPLAY_DESCRIPTION     VARCHAR2(256 BYTE),
         DEVICE_CATEGORY_ID      NUMBER(38,0),
         DEVICE_SUB_CATEGORY_ID  NUMBER(38,0),
         DEVICE_BRAND_ID         NUMBER(38,0),
         PARENT_ID               NUMBER(38,0),
         POWERED_BY              VARCHAR2(256 BYTE),
         CARRIER                 VARCHAR2(256 BYTE),
         CAPABILITY_SET_ID       NUMBER(38,0),
         CREATED_BY              VARCHAR2(32 BYTE),
         CREATED_DATE  DATE,
         UPDATED_BY  VARCHAR2(32 BYTE),
         UPDATED_DATE  DATE,
         POWERED_BY_DEVICE_TYPE    VARCHAR2(64 BYTE),
         OPERATING_SYSTEM          VARCHAR2(32 BYTE),
         OPERATING_SYSTEM_VERSION  VARCHAR2(32 BYTE),
         BROWSER                   VARCHAR2(32 BYTE),
         BROWSER_VERSION           VARCHAR2(32 BYTE),
         CLASSIFICATION            VARCHAR2(32 BYTE),
        CONSTRAINT  PK_DEVICE_TYPE  PRIMARY KEY ( DEVICE_TYPE_ID));
    CREATE INDEX  DEVICE_TYPE_IDX  ON  DEVICE_TYPE
         CAPABILITY_SET_ID ,
        UPPER( PARTNER_DEVICE_TYPE )
    CREATE TABLE DIGITAL_COMPATIBILITY
        DIGITAL_COMPATIBILITY_ID NUMBER NOT NULL ENABLE,
        CAPABILITY_SET_ID        NUMBER,
        OBJECT_TYPE              VARCHAR2(38 BYTE) NOT NULL ENABLE,
        CREATED_DATE DATE NOT NULL ENABLE,
        CREATED_BY VARCHAR2(38 BYTE) NOT NULL ENABLE,
        UPDATED_DATE DATE NOT NULL ENABLE,
        UPDATED_BY        VARCHAR2(38 BYTE) NOT NULL ENABLE,
        OBJECT_ID         VARCHAR2(114 BYTE),
        ENCODE_PROFILE_ID NUMBER
    CREATE INDEX ENCODE_PROFILE_ID_IDX ON DIGITAL_COMPATIBILITY
        ENCODE_PROFILE_ID,
        OBJECT_ID,
        OBJECT_TYPE
             Query
    =====
    EXPLAIN PLAN FOR
    SELECT  /*+ INDEX(dc, ENCODE_PROFILE_ID_IDX) */
    DISTINCT dc.object_id AS title_id
    FROM digital_compatibility dc,
      device_type dt
    WHERE dc.capability_set_id        = dt.capability_set_id
    AND upper(dt.partner_device_type) = :1
    AND dc.object_id                 IN (:2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27, :28, :29, :30, :31, :32, :33)
    AND dc.object_type                =:"SYS_B_0";
                                 Explain plan
    | Id  | Operation                       | Name                  | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                |                       |     2 |   472 |   274   (4)|
    |   1 |  HASH UNIQUE                    |                       |     2 |   472 |   274   (4)|
    |*  2 |   MAT_VIEW ACCESS BY INDEX ROWID| DIGITAL_COMPATIBILITY |     1 |    93 |    68   (3)|
    |   3 |    NESTED LOOPS                 |                       |     2 |   472 |   273   (4)|
    |*  4 |     INDEX FULL SCAN             | DEVICE_TYPE_IDX       |     4 |   572 |     1   (0)|
    |*  5 |     INDEX FULL SCAN             | ENCODE_PROFILE_ID_IDX |     8 |       |    67   (3)|
    Predicate Information (identified by operation id):
       2 - filter("DC"."CAPABILITY_SET_ID"="DT"."CAPABILITY_SET_ID")
       4 - access(UPPER("PARTNER_DEVICE_TYPE")=:1)
           filter(UPPER("PARTNER_DEVICE_TYPE")=:1)
       5 - access("DC"."OBJECT_TYPE"=:SYS_B_0)
           filter(("DC"."OBJECT_ID"=:2 OR "DC"."OBJECT_ID"=:3 OR "DC"."OBJECT_ID"=:4 OR
                  "DC"."OBJECT_ID"=:5 OR "DC"."OBJECT_ID"=:6 OR "DC"."OBJECT_ID"=:7 OR
                  "DC"."OBJECT_ID"=:8 OR "DC"."OBJECT_ID"=:9 OR "DC"."OBJECT_ID"=:10 OR
                  "DC"."OBJECT_ID"=:11 OR "DC"."OBJECT_ID"=:12 OR "DC"."OBJECT_ID"=:13 OR
                  "DC"."OBJECT_ID"=:14 OR "DC"."OBJECT_ID"=:15 OR "DC"."OBJECT_ID"=:16 OR
                  "DC"."OBJECT_ID"=:17 OR "DC"."OBJECT_ID"=:18 OR "DC"."OBJECT_ID"=:19 OR
                  "DC"."OBJECT_ID"=:20 OR "DC"."OBJECT_ID"=:21 OR "DC"."OBJECT_ID"=:22 OR
                  "DC"."OBJECT_ID"=:23 OR "DC"."OBJECT_ID"=:24 OR "DC"."OBJECT_ID"=:25 OR
                  "DC"."OBJECT_ID"=:26 OR "DC"."OBJECT_ID"=:27 OR "DC"."OBJECT_ID"=:28 OR
                  "DC"."OBJECT_ID"=:29 OR "DC"."OBJECT_ID"=:30 OR "DC"."OBJECT_ID"=:31 OR
                  "DC"."OBJECT_ID"=:32 OR "DC"."OBJECT_ID"=:33) AND "DC"."OBJECT_TYPE"=:SYS_B_0)
    Note
       - 'PLAN_TABLE' is old version
                               Trace
    recursive calls     280
    db block gets     16
    consistent gets     97
    physical reads     0
    redo size     3224
    bytes sent via SQL*Net to client     589
    bytes received via SQL*Net from client     1598
    SQL*Net roundtrips to/from client     2
    sorts (memory)     4
    sorts (disk)     0
                            Thanks ....

    You index on DIGITAL_COMPATIBILITY is on ENCODE_PROFILE_ID, OBJECT_ID, OBJECT_TYPE
    But you query for object_id and object_type.
    How much rows you you identify with this? What the PK?
    The way it's now, it needs to read the full index, then the table and as DEVICE_TYPE is small it makes a NL to it.
    Makes sense.
    If you would add an index on OBJECT_ID, OBJECT_TYPE and capability_set_id ORACLE would just need to read the INDEX.

  • Explain plan doubt.

    I have done 'explain plan' for this query:-
    explain plan for
    select MD.* from ppbs_mobile_detail MD, ppbs_inv_sim_serial ISS where MD.LATEST_SIM_SERIAL_NO=ISS.SIM_SERIAL_NO
    and MD.MOBILE_NO=ISS.MOBILE_NO
    which is having indexes on all the four columns of the 2 tables used: LATEST_SIM_SERIAL_NO,SIM_SERIAL_NO,MOBILE_NO,
    MOBILE_NO.
    But only 1 index on mobile no. of ppbs_mobile_detail is firing.
    Is that, indexes on only 1 table should fire.
    I hope, my question is clear. Please help in solving the doubt.
    Regards.

    thanks for ur update.
    i tried, @?/rdbms/admin/utlxplan.sql but it was giving a error like 'unable to open file "?/rdbms/admin/utlxplan.sql"'.
    So, i re-created the table.
    I gave both the analyze statements,
    SQL> analyze table PPBS_INV_SIM_SERIAL compute statistics for table for all indexed columns for all indexes ;
    SQL> analyze table PPBS_MOBILE_DETAIL compute statistics for table for all indexed columns for all indexes ;
    Output of select * from TABLE(dbms_xplan.display) is:-
    | Id | Operation | Name | Rows | Bytes | Cost |
    | 0 | SELECT STATEMENT | | 1 | 164 | 21174 |
    | 1 | HASH JOIN | | 1 | 164 | 21174 |
    | 2 | TABLE ACCESS FULL | PPBS_INV_SIM_SERIAL | 3221K| 86M| 9772 |
    | 3 | TABLE ACCESS FULL | PPBS_MOBILE_DETAIL | 1469K| 190M| 2718 |
    Note: cpu costing is off, PLAN_TABLE' is old version
    regards.

  • Partition of table n Explain plan

    I am a newbie for oracle partititon. Need help!!!
    I have a created a partition table, range partition by key column datatype is 'timetamp'.
    Stucture would be ::
    CREATE TABLE sales
      ( prod_id       NUMBER(6)
      , cust_id       NUMBER
      , time_id       DATE
      , amount_sold   NUMBER(10,2)
    PARTITION BY RANGE (time_id)
    ( PARTITION sales_q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy'))
    , PARTITION sales_q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006','dd-MON-yyyy'))
    , PARTITION sales_q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy'))
    , PARTITION sales_q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy'))
    The time i run below query, explain plan shows PStart as #1 and PStop as #4, but this date range access only one partition, explain plan must show particular partition. Also should it show partition name?
    select * from sales where trunc(time_id)=trunc(sysdate-2811);

    Thanks for the reply martin,I have tried below query still it goes for all partitions.Please refer to below Expalin Plan.
    select * from sales where trunc(time_id) between trunc(sysdate-2811) and trunc(sysdate-2810) -1/86400
    <PlanElement id="0" operation="SELECT STATEMENT" optimizer="ALL_ROWS" cost="42" cardinality="1" bytes="48" cpu_cost="1,321,416" io_cost="42" time="1">
    <PlanElements>
    <PlanElement id="1" operation="FILTER" qblock_name="SEL$1" filter_predicates="TRUNC(SYSDATE@!-2811)<=TRUNC(SYSDATE@!-2810)-.00001157407407407407407407407407407407407407">
    <PlanElements>
    <PlanElement id="2" operation="PARTITION RANGE" option="ALL" cost="42" cardinality="1" bytes="48" partition_id="2" partition_start="1" partition_stop="4" cpu_cost="1,321,416" io_cost="42" time="1">
    <PlanElements>
    <PlanElement object_ID="0" id="3" operation="TABLE ACCESS" option="FULL" object_owner="SONARDBO" object_name="SALES" object_type="TABLE" object_instance="1" cost="42" cardinality="1" bytes="48" partition_id="2" partition_start="1" partition_stop="4" cpu_cost="1,321,416" io_cost="42" qblock_name="SEL$1" filter_predicates="TRUNC(INTERNAL_FUNCTION("TIME_ID"))>=TRUNC(SYSDATE@!-2811) AND TRUNC(INTERNAL_FUNCTION("TIME_ID"))<=TRUNC(SYSDATE@!-2810)-.00001157407407407407407407407407407407407407" time="1" />

  • How to explain plan with bind variable

    I want to explain plan for query which contains bind variables. I try to execute the query "explain plan for <query>" using PreparedStatement. If I set the bind variable using setXxx method, I get "ORA-01006: bind variable does not exist" error, if I don't bind, I get "java.sql.SQLException: Missing IN or OUT parameter at index:: 1". First error seems to be generated by JDBC driver, the second by the database. Problem is, that database does not require the bind variables to be bound, but the drivers does. Is there any way to do it?
    I use JDBC 10.1.0.5.0, database is Oracle9i Enterprise Edition Release 9.2.0.6.0.
    Thanks in advance,
    Viliam

    hope this helps;
    SQL> set pagesize 25
    SQL> set linesize 141
    SQL> explain plan for
    2 select ename from emp where ename = :x ;
    Explained.
    SQL> SELECT * FROM table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3956160932
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 6 | 2 (0)| 00:00:01 |
    |* 1 | TABLE ACCESS FULL| EMP | 1 | 6 | 2 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    1 - filter("ENAME"=:X)
    13 rows selected.
    http://psoug.org/reference/explain_plan.html
    http://psoug.org/reference/dbms_xplan.html

  • Query tunning in Oracle using Explain Plan

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

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

  • Same query, same dataset, same ddl setup, but wildly different explain plan

    Hello o fountains of oracle knowledge!
    We have a problem that caused us a full stop when rolling out a new version of our system to a customer and a whole Sunday to boot.
    The scenario is as follows:
    1. An previous version database schema
    2. The current version database schema
    3. A migration script to migrate the old schema to the new
    So we perform the following migration:
    1. Export the previous version database schema
    2. Import into a new schema called schema_old
    3. Create a new schema called schema_new
    4. Run migration script which creates objects, copies data, creates indexes etc etc in schema_new
    The migration runs fine in all environments (development, test and production)
    In our development and test environments performance is stellar, on the customer production server the performance is terrible.
    This using the exact same export file (from the production environment) and performing the exact same steps with the exact same migration script.
    Database version is 10.2.0.1.0 EE on all databases. OS is Microsoft Windows Server 2003 EE SP2 on all servers.
    The system is not in any sense under a heavy load (we have tested with no other load than ourselves).
    Looking at the explain plan for a query that is run frequently and does not use bind variables we see wildly different explain plans.
    The explain plan cost on our development and test servers is estimated to *7* for this query and there are no full table scans.
    On the production server the cost is *8433* and there are two full table scans of which one is on the largest table.
    We have tried to run analyse on all objects with very little effect. The plan changed very slightly, but still includes the two full table scans on the problem server and the cost is still the same.
    All tables and indexes are identical (including storage options), created from the same migration script.
    I am currently at loss for where to look? What can be causing this? I assume this could be caused by some parameter that is set on the server, but I don't know what to look for.
    I would be very grateful for any pointers.
    Thanks,
    Håkon

    Thank you for your answer.
    We collected statistics only after we determined that the production server where not behaving according to expectations.
    In this case we used TOAD and the tool within to collect statistics for all objects. We used 'Analyze' and 'Compute Statistics' options.
    I am not an expert, so sorry if this is too naive an approach.
    Here is the query:SELECT count(0)  
    FROM score_result sr, web_scorecard sc, product p
    WHERE sr.score_final_decision like 'VENT%'  
    AND sc.CREDIT_APPLICATION_ID = sr.CREDIT_APPLICATION_ID  
    AND sc.application_complete='Y'   
    AND p.product = sc.web_product   
    AND p.inactive_product = '2' ;I use this as an example, but the problem exists for virtually all queries.
    The output from the 'good' server:
    | Id  | Operation                      | Name                  | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT               |                       |     1 |    39 |     7   (0)|
    |   1 |  SORT AGGREGATE                |                       |     1 |    39 |            |
    |   2 |   NESTED LOOPS                 |                       |     1 |    39 |     7   (0)|
    |   3 |    NESTED LOOPS                |                       |     1 |    30 |     6   (0)|
    |   4 |     TABLE ACCESS BY INDEX ROWID| SCORE_RESULT          |     1 |    17 |     4   (0)|
    |   5 |      INDEX RANGE SCAN          | SR_FINAL_DECISION_IDX |     1 |       |     3   (0)|
    |   6 |     TABLE ACCESS BY INDEX ROWID| WEB_SCORECARD         |     1 |    13 |     2   (0)|
    |   7 |      INDEX UNIQUE SCAN         | WEB_SCORECARD_PK      |     1 |       |     1   (0)|
    |   8 |    TABLE ACCESS BY INDEX ROWID | PRODUCT               |     1 |     9 |     1   (0)|
    |   9 |     INDEX UNIQUE SCAN          | PK_PRODUCT            |     1 |       |     0   (0)|
    ---------------------------------------------------------------------------------------------The output from the 'bad' server:
    | Id  | Operation                 | Name                  | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT          |                       |     1 |    32 |  8344   (3)|
    |   1 |  SORT AGGREGATE           |                       |     1 |    32 |            |
    |   2 |   HASH JOIN               |                       | 10887 |   340K|  8344   (3)|
    |   3 |    TABLE ACCESS FULL      | PRODUCT               |     6 |    42 |     3   (0)|
    |   4 |    HASH JOIN              |                       | 34381 |   839K|  8340   (3)|
    |   5 |     VIEW                  | index$_join$_001      | 34381 |   503K|  2193   (3)|
    |   6 |      HASH JOIN            |                       |       |       |            |
    |   7 |       INDEX RANGE SCAN    | SR_FINAL_DECISION_IDX | 34381 |   503K|   280   (3)|
    |   8 |       INDEX FAST FULL SCAN| SCORE_RESULT_PK       | 34381 |   503K|  1371   (2)|
    |   9 |     TABLE ACCESS FULL     | WEB_SCORECARD         |   489K|  4782K|  6137   (4)|
    ----------------------------------------------------------------------------------------I hope the formatting makes this readable.
    Stats (from SQL Developer), good table:NUM_ROWS     489716
    BLOCKS     27198
    AVG_ROW_LEN     312
    SAMPLE_SIZE     489716
    LAST_ANALYZED     15.12.2009
    LAST_ANALYZED_SINCE     15.12.2009Stats (from SQL Developer), bad table:
    NUM_ROWS     489716
    BLOCKS     27199
    AVG_ROW_LEN     395
    SAMPLE_SIZE     489716
    LAST_ANALYZED     17.12.2009
    LAST_ANALYZED_SINCE     17.12.2009I'm unsure what would cause the difference in average row length.
    I could obviously try to tune our sql-statements to work on the server not behaving better, but I would rather understand why they are different and make sure that we can expect similar behaviour between environments.
    Thank you again for trying to help me.
    Håkon
    Edited by: ergates on 17.des.2009 05:57
    Edited by: ergates on 17.des.2009 06:02

  • Explain plan for same query in three databases

    Hi,
    We have three databases dev, uat and test, all have same init parameters and almost same data. We are running a query which runs long on dev and on uat and test it runs very fast, the explain plan on uat and test shows a cost of around 4000 but on dev the cost is 20000. Statistics were collected on three instances 2 days ago and the objects are also same.
    My question is what else should I look for this optimizer behaviour? the database version is 10.2.0.3.
    Please help.
    Thanks
    Clin

    user627471 wrote:
    Hi,
    We have three databases dev, uat and test, all have same init parameters and almost same data. We are running a query which runs long on dev and on uat and test it runs very fast, the explain plan on uat and test shows a cost of around 4000 but on dev the cost is 20000. Statistics were collected on three instances 2 days ago and the objects are also same.
    My question is what else should I look for this optimizer behaviour? the database version is 10.2.0.3.
    Please help.
    Thanks
    Clinpost both EXPLAIN PLAN here

  • Query Performance and reading an Explain Plan

    Hi,
    Below I have posted a query that is running slowly for me - upwards of 10 minutes which I would not expect. I have also supplied the explain plan. I'm fairly new to explain plans and not sure what the danger signs are that I should be looking out for.
    I have added indexes to these tables, a lot of which are used in the JOIN and so I expected this to be quicker.
    Any help or pointers in the right direction would be very much appreciated -
    SELECT a.lot_id, a.route, a.route_rev
    FROM wlos_owner.tbl_current_lot_status_dim a, wlos_owner.tbl_last_seq_num b, wlos_owner.tbl_hist_metrics_at_op_lkp c
    WHERE a.fw_ver = '2'
    AND a.route = b.route
    AND a.route_rev = b.route_rev
    AND a.fw_ver = b.fw_ver
    AND a.route = c.route
    AND a.route_rev = c.route_rev
    AND a.fw_ver = c.fw_ver
    AND a.prod = c.prod
    AND a.lot_type = c.lot_type
    AND c.step_seq_num >= a.step_seq_num
    PLAN_TABLE_OUTPUT
    Plan hash value: 2447083104
    | Id  | Operation           | Name                       | Rows  | Bytes | Cost
    (%CPU)| Time     |
    PLAN_TABLE_OUTPUT
    |   0 | SELECT STATEMENT    |                            |   333 | 33633 |  1347
       (8)| 00:00:17 |
    |*  1 |  HASH JOIN          |                            |   333 | 33633 |  1347
       (8)| 00:00:17 |
    |*  2 |   HASH JOIN         |                            |   561 | 46002 |  1333
       (7)| 00:00:17 |
    |*  3 |    TABLE ACCESS FULL| TBL_CURRENT_LOT_STATUS_DIM | 11782 |   517K|   203
       (5)| 00:00:03 |
    PLAN_TABLE_OUTPUT
    |*  4 |    TABLE ACCESS FULL| TBL_HIST_METRICS_AT_OP_LKP |   178K|  6455K|  1120
       (7)| 00:00:14 |
    |*  5 |   TABLE ACCESS FULL | TBL_LAST_SEQ_NUM           |  8301 |   154K|    13
      (16)| 00:00:01 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       1 - access("A"."ROUTE"="B"."ROUTE" AND "A"."ROUTE_REV"="B"."ROUTE_REV" AND
                  "A"."FW_VER"=TO_NUMBER("B"."FW_VER"))
       2 - access("A"."ROUTE"="C"."ROUTE" AND "A"."ROUTE_REV"="C"."ROUTE_REV" AND
                  "A"."FW_VER"="C"."FW_VER" AND "A"."PROD"="C"."PROD" AND "A"."LOT_T
    YPE"="C"."LOT_TYPE")
           filter("C"."STEP_SEQ_NUM">="A"."STEP_SEQ_NUM")
       3 - filter("A"."FW_VER"=2)
    PLAN_TABLE_OUTPUT
       4 - filter("C"."FW_VER"=2)
       5 - filter(TO_NUMBER("B"."FW_VER")=2)
    24 rows selected.

    Guys thank you for your help.
    I changed the type of the offending column and the plan looks a lot better and results seem a lot quicker.
    However I have added to my SELECT, quite substantially, and have a new explain plan.
    There are two sections in particular that have a high cost and I was wondering if you seen anything inherently wrong or can explain more fully what the PLAN_TABLE_OUTPUT descriptions are telling me - in particular
    INDEX FULL SCAN
    PLAN_TABLE_OUTPUT
    Plan hash value: 3665357134
    | Id  | Operation                        | Name                           | Rows
      | Bytes | Cost (%CPU)| Time     |
    PLAN_TABLE_OUTPUT
    |   0 | SELECT STATEMENT                 |                                |
    4 |   316 |    52   (2)| 00:00:01 |
    |*  1 |  VIEW                            |                                |
    4 |   316 |    52   (2)| 00:00:01 |
    |   2 |   WINDOW SORT                    |                                |
    4 |   600 |    52   (2)| 00:00:01 |
    |*  3 |    TABLE ACCESS BY INDEX ROWID   | TBL_HIST_METRICS_AT_OP_LKP     |
    1 |    71 |     1   (0)| 00:00:01 |
    PLAN_TABLE_OUTPUT
    |   4 |     NESTED LOOPS                 |                                |
    4 |   600 |    51   (0)| 00:00:01 |
    |   5 |      NESTED LOOPS                |                                |    7
    5 |  5925 |    32   (0)| 00:00:01 |
    |*  6 |       INDEX FULL SCAN            | UNIQUE_LAST_SEQ                |    8
    9 |  2492 |    10   (0)| 00:00:01 |
    |   7 |       TABLE ACCESS BY INDEX ROWID| TBL_CURRENT_LOT_STATUS_DIM     |
    PLAN_TABLE_OUTPUT
    1 |    51 |     1   (0)| 00:00:01 |
    |*  8 |        INDEX RANGE SCAN          | TBL_CUR_LOT_STATUS_DIM_IDX1    |
    1 |       |     1   (0)| 00:00:01 |
    |*  9 |      INDEX RANGE SCAN            | TBL_HIST_METRIC_AT_OP_LKP_IDX1 |    2
    9 |       |     1   (0)| 00:00:01 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       1 - filter("SEQ"=1)
       3 - filter("C"."FW_VER"=2 AND "A"."PROD"="C"."PROD" AND "A"."LOT_TYPE"="C"."L
    OT_TYPE" AND
                  "C"."STEP_SEQ_NUM">="A"."STEP_SEQ_NUM")
       6 - access("B"."FW_VER"=2)
           filter("B"."FW_VER"=2)
    PLAN_TABLE_OUTPUT
       8 - access("A"."ROUTE"="B"."ROUTE" AND "A"."ROUTE_REV"="B"."ROUTE_REV" AND "A
    "."FW_VER"=2)
       9 - access("A"."ROUTE"="C"."ROUTE" AND "A"."ROUTE_REV"="C"."ROUTE_REV")

  • Need help in SQL Explain plan

    Hi,
    I was trying to get an explain plan for below query. (Refer - A)
    BILL_DETAIL table have index of ZONECODE,MRNO,AREACODE,WCNO but still it's
    showing 'TABLE ACCESS FULL in BILL_DETAIL'
    If i select only first 4 column, it is going by index. (REFER - B)
    As per my knowledge index will consider only where clause conditions
    but here I couldn't understand why this considering select output columns.
    First time I am trying sql explain plan statement, Please help me to correct
    this query.
    REFER - A
    EXPLAIN PLAN FOR
    SELECT B.ZONECODE ZONECODE, B.MRNO MRNO, B.AREACODE AREACODE, B.WCNO WCNO,
    B.BILLNO BILLNO,B.BILLDT BILLDT,B.FROMDT FROMDT,B.TODT TODT,B.TOBEPAID TOBEPAID,
    B.PREVUNPAID PREVUNPAID,B.DUEDT DUEDT
    FROM BILL_DETAIL B, CONSUMER_MASTER C
    WHERE B.ZONECODE = C.ZONECODE
    AND B.MRNO = C.MRNO
    AND B.AREACODE = C.AREACODE
    AND B.WCNO = C.WCNO
    AND UPPER(B.ZONECODE)=UPPER('SZ-4')
    AND UPPER(B.MRNO)=UPPER('347')
    AND UPPER(B.AREACODE)=UPPER('18')
    AND UPPER(B.WCNO)=UPPER('30910')
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
    | 0 | SELECT STATEMENT | | 1 | 71 | 9 (0)|
    | 1 | NESTED LOOPS | | 1 | 71 | 9 (0)|
    |* 2 | TABLE ACCESS FULL| BILL_DETAIL | 1 | 52 | 9 (0)|
    |* 3 | INDEX UNIQUE SCAN| SYS_C008803 | 1 | 19 | 0 (0)|
    Predicate Information (identified by operation id):
    2 - filter(UPPER("B"."ZONECODE")='SZ-4' AND UPPER("B"."MRNO")='347'
    AND UPPER("B"."AREACODE")='18' AND UPPER("B"."WCNO")='30910')
    3 - access("B"."ZONECODE"="C"."ZONECODE" AND "B"."MRNO"="C"."MRNO"
    AND "B"."AREACODE"="C"."AREACODE" AND "B"."WCNO"="C"."WCNO")
    REFER - B
    EXPLAIN PLAN FOR
    SELECT B.ZONECODE ZONECODE, B.MRNO MRNO, B.AREACODE AREACODE, B.WCNO WCNO
    FROM BILL_DETAIL B, CONSUMER_MASTER C
    WHERE B.ZONECODE = C.ZONECODE
    AND B.MRNO = C.MRNO
    AND B.AREACODE = C.AREACODE
    AND B.WCNO = C.WCNO
    AND UPPER(B.ZONECODE)=UPPER('SZ-4')
    AND UPPER(B.MRNO)=UPPER('347')
    AND UPPER(B.AREACODE)=UPPER('18')
    AND UPPER(B.WCNO)=UPPER('30910')
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
    | 0 | SELECT STATEMENT | | 1 | 34 | 4 (0)|
    | 1 | NESTED LOOPS | | 1 | 34 | 4 (0)|
    |* 2 | INDEX FAST FULL SCAN| SYS_C008798 | 1 | 15 | 4 (0)|
    |* 3 | INDEX UNIQUE SCAN | SYS_C008803 | 1 | 19 | 0 (0)|
    Predicate Information (identified by operation id):
    2 - filter(UPPER("B"."ZONECODE")='SZ-4' AND UPPER("B"."MRNO")='347'
    AND UPPER("B"."AREACODE")='18' AND UPPER("B"."WCNO")='30910')
    3 - access("B"."ZONECODE"="C"."ZONECODE" AND "B"."MRNO"="C"."MRNO"
    AND "B"."AREACODE"="C"."AREACODE" AND "B"."WCNO"="C"."WCNO")
    Note
    - 'PLAN_TABLE' is old version

    Welcome to the forums!
    user13295080 wrote:
    I was trying to get an explain plan for below query. (Refer - A)
    BILL_DETAIL table have index of ZONECODE,MRNO,AREACODE,WCNO but still it's
    showing 'TABLE ACCESS FULL in BILL_DETAIL'
    If i select only first 4 column, it is going by index. (REFER - B)
    As per my knowledge index will consider only where clause conditions
    but here I couldn't understand why this considering select output columns.This is because Oracle is smart enough to know that the entire query can be satisfied by using the index without hitting the table. However, once you add a column that doesn't exist in the index Oracle has decided it is more efficient to use the full table scan.
    I also noticed that all the row estimates are 1 in the execution plans. Is this expected? If not, have statistics on the relevant objects been gathered?
    Generally speaking, when you have a query tuning question providing information in these threads is extremely helpful:
    {message:id=1812597}
    {thread:id=863295}
    Additionally, when posting query plans, queries, or any code please use \ tags to preserve formatting.
    Your code here!\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Query with diff. explain plans

    Hi,
    Our query returns different execution plans in Prod and non-prod. It is slow in PROD. The data size is the same in both DBs and stats are gathered at 50% estimate for both schemas:
    Prod (slow) explain plan:
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 852 | 33 (4)| 00:00:01 |
    |* 1 | FILTER | | | | | |
    | 2 | HASH GROUP BY | | 1 | 852 | 33 (4)| 00:00:01 |
    | 3 | NESTED LOOPS | | 1 | 852 | 32 (0)| 00:00:01 |
    | 4 | NESTED LOOPS | | 1 | 802 | 31 (0)| 00:00:01 |
    | 5 | NESTED LOOPS OUTER | | 1 | 785 | 30 (0)| 00:00:01 |
    | 6 | NESTED LOOPS OUTER | | 1 | 742 | 29 (0)| 00:00:01 |
    | 7 | NESTED LOOPS | | 1 | 732 | 29 (0)| 00:00:01 |
    | 8 | NESTED LOOPS | | 1 | 678 | 26 (0)| 00:00:01 |
    | 9 | NESTED LOOPS | | 1 | 666 | 26 (0)| 00:00:01 |
    | 10 | NESTED LOOPS | | 1 | 623 | 25 (0)| 00:00:01 |
    | 11 | NESTED LOOPS | | 1 | 580 | 24 (0)| 00:00:01 |
    | 12 | NESTED LOOPS | | 1 | 576 | 24 (0)| 00:00:01 |
    | 13 | NESTED LOOPS | | 2 | 1076 | 13 (0)| 00:00:01 |
    | 14 | NESTED LOOPS | | 2 | 1040 | 13 (0)| 00:00:01 |
    | 15 | NESTED LOOPS | | 2 | 1028 | 13 (0)| 00:00:01 |
    | 16 | NESTED LOOPS | | 2 | 996 | 13 (0)| 00:00:01 |
    | 17 | NESTED LOOPS | | 2 | 988 | 13 (0)| 00:00:01 |
    | 18 | NESTED LOOPS | | 2 | 954 | 13 (0)| 00:00:01 |
    | 19 | NESTED LOOPS | | 2 | 944 | 13 (0)| 00:00:01 |
    | 20 | NESTED LOOPS | | 2 | 920 | 13 (0)| 00:00:01 |
    | 21 | NESTED LOOPS | | 2 | 912 | 13 (0)| 00:00:01 |
    | 22 | NESTED LOOPS | | 2 | 826 | 11 (0)| 00:00:01 |
    | 23 | NESTED LOOPS | | 1 | 370 | 9 (0)| 00:00:01 |
    | 24 | NESTED LOOPS | | 1 | 306 | 8 (0)| 00:00:01 |
    | 25 | NESTED LOOPS | | 1 | 263 | 7 (0)| 00:00:01 |
    | 26 | NESTED LOOPS | | 1 | 220 | 6 (0)| 00:00:01 |
    | 27 | NESTED LOOPS | | 1 | 177 | 5 (0)| 00:00:01 |
    | 28 | NESTED LOOPS | | 1 | 129 | 4 (0)| 00:00:01 |
    | 29 | NESTED LOOPS | | 1 | 86 | 3 (0)| 00:00:01 |
    | 30 | TABLE ACCESS BY INDEX ROWID| SYMMETADATA | 1 | 43 | 2 (0)| 00:00:01 |
    |* 31 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 1 (0)| 00:00:01 |
    | 32 | TABLE ACCESS BY INDEX ROWID| SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 33 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 34 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 35 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 36 | TABLE ACCESS BY INDEX ROWID | TPRODUCT | 1 | 48 | 1 (0)| 00:00:01 |
    |* 37 | INDEX UNIQUE SCAN | TPRODUCT_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 38 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 39 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 40 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 41 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 42 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 43 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 44 | TABLE ACCESS BY INDEX ROWID | TPRODUCT | 1 | 64 | 1 (0)| 00:00:01 |
    |* 45 | INDEX UNIQUE SCAN | TPRODUCT_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 46 | INLIST ITERATOR | | | | | |
    | 47 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 2 | 86 | 2 (0)| 00:00:01 |
    |* 48 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 2 | | 1 (0)| 00:00:01 |
    | 49 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 50 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    |* 51 | INDEX UNIQUE SCAN | SYMUSERCOUNT_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 52 | INDEX UNIQUE SCAN | SYMUSERCOUNT_PK | 1 | 12 | 0 (0)| 00:00:01 |
    |* 53 | INDEX UNIQUE SCAN | SYMSKUTYPE_PK | 1 | 5 | 0 (0)| 00:00:01 |
    |* 54 | INDEX UNIQUE SCAN | SYMSKUTYPE_PK | 1 | 17 | 0 (0)| 00:00:01 |
    |* 55 | INDEX UNIQUE SCAN | SYMSKULANGUAGE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 56 | INDEX UNIQUE SCAN | SYMSKULANGUAGE_PK | 1 | 16 | 0 (0)| 00:00:01 |
    |* 57 | INDEX UNIQUE SCAN | SYMVENDOR_PK | 1 | 6 | 0 (0)| 00:00:01 |
    |* 58 | INDEX UNIQUE SCAN | SYMVENDOR_PK | 1 | 18 | 0 (0)| 00:00:01 |
    | 59 | TABLE ACCESS BY INDEX ROWID | SYMPRODUCTSKU | 1 | 38 | 6 (0)| 00:00:01 |
    |* 60 | INDEX RANGE SCAN | I_PSKU_MERCH_LOOKUP | 1 | | 5 (0)| 00:00:01 |
    |* 61 | INDEX UNIQUE SCAN | SYMMEDIATYPE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 62 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 63 | INDEX UNIQUE SCAN | SYMMETADATA_PK | 1 | | 0 (0)| 00:00:01 |
    | 64 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 65 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    |* 66 | INDEX UNIQUE SCAN | SYMMEDIATYPE_PK | 1 | 12 | 0 (0)| 00:00:01 |
    | 67 | TABLE ACCESS BY INDEX ROWID | SYMPRODUCTSKU | 1 | 54 | 3 (0)| 00:00:01 |
    |* 68 | INDEX RANGE SCAN | I_PSKU_MERCH_LOOKUP | 1 | | 2 (0)| 00:00:01 |
    |* 69 | INDEX UNIQUE SCAN | SYMPCCOUNT_PK | 1 | 10 | 0 (0)| 00:00:01 |
    | 70 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 43 | 1 (0)| 00:00:01 |
    |* 71 | INDEX UNIQUE SCAN | SYMMETADATA_PK | 1 | | 0 (0)| 00:00:01 |
    |* 72 | TABLE ACCESS BY INDEX ROWID | TPRODUCTSKU | 1 | 17 | 1 (0)| 00:00:01 |
    |* 73 | INDEX UNIQUE SCAN | TPRODUCTSKU_PK | 1 | | 0 (0)| 00:00:01 |
    |* 74 | TABLE ACCESS BY INDEX ROWID | TPRODUCTSKU | 1 | 50 | 1 (0)| 00:00:01 |
    |* 75 | INDEX UNIQUE SCAN | TPRODUCTSKU_PK | 1 | | 0 (0)| 00:00:01 |
    Non Prod (Fast) Plan:
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 383 | 28 (0)| 00:00:01 |
    |* 1 | FILTER | | | | | |
    | 2 | NESTED LOOPS | | 1 | 383 | 17 (0)| 00:00:01 |
    | 3 | NESTED LOOPS OUTER | | 1 | 350 | 16 (0)| 00:00:01 |
    | 4 | NESTED LOOPS | | 1 | 308 | 15 (0)| 00:00:01 |
    | 5 | NESTED LOOPS | | 1 | 266 | 14 (0)| 00:00:01 |
    | 6 | NESTED LOOPS OUTER | | 1 | 262 | 14 (0)| 00:00:01 |
    | 7 | NESTED LOOPS | | 1 | 258 | 14 (0)| 00:00:01 |
    | 8 | NESTED LOOPS | | 2 | 438 | 7 (0)| 00:00:01 |
    | 9 | NESTED LOOPS | | 2 | 428 | 7 (0)| 00:00:01 |
    | 10 | NESTED LOOPS | | 2 | 420 | 7 (0)| 00:00:01 |
    | 11 | NESTED LOOPS | | 2 | 410 | 7 (0)| 00:00:01 |
    | 12 | NESTED LOOPS | | 2 | 402 | 7 (0)| 00:00:01 |
    | 13 | NESTED LOOPS | | 1 | 159 | 5 (0)| 00:00:01 |
    | 14 | NESTED LOOPS | | 1 | 126 | 4 (0)| 00:00:01 |
    | 15 | NESTED LOOPS | | 1 | 84 | 3 (0)| 00:00:01 |
    | 16 | TABLE ACCESS BY INDEX ROWID| SYMMETADATA | 1 | 42 | 2 (0)| 00:00:01 |
    |* 17 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 1 (0)| 00:00:01 |
    | 18 | TABLE ACCESS BY INDEX ROWID| SYMMETADATA | 1 | 42 | 1 (0)| 00:00:01 |
    |* 19 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 20 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 42 | 1 (0)| 00:00:01 |
    |* 21 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 22 | TABLE ACCESS BY INDEX ROWID | TPRODUCT | 1 | 33 | 1 (0)| 00:00:01 |
    |* 23 | INDEX UNIQUE SCAN | TPRODUCT_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 24 | INLIST ITERATOR | | | | | |
    | 25 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 2 | 84 | 2 (0)| 00:00:01 |
    |* 26 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 2 | | 1 (0)| 00:00:01 |
    |* 27 | INDEX UNIQUE SCAN | SYMUSERCOUNT_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 28 | INDEX UNIQUE SCAN | SYMSKUTYPE_PK | 1 | 5 | 0 (0)| 00:00:01 |
    |* 29 | INDEX UNIQUE SCAN | SYMSKULANGUAGE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 30 | INDEX UNIQUE SCAN | SYMVENDOR_PK | 1 | 5 | 0 (0)| 00:00:01 |
    | 31 | TABLE ACCESS BY INDEX ROWID | SYMPRODUCTSKU | 1 | 39 | 4 (0)| 00:00:01 |
    |* 32 | INDEX RANGE SCAN | I_PSKU_MERCH_LOOKUP | 1 | | 3 (0)| 00:00:01 |
    |* 33 | INDEX UNIQUE SCAN | SYMPCCOUNT_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 34 | INDEX UNIQUE SCAN | SYMMEDIATYPE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 35 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 42 | 1 (0)| 00:00:01 |
    |* 36 | INDEX UNIQUE SCAN | SYMMETADATA_PK | 1 | | 0 (0)| 00:00:01 |
    | 37 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 42 | 1 (0)| 00:00:01 |
    |* 38 | INDEX UNIQUE SCAN | SYMMETADATA_PK | 1 | | 0 (0)| 00:00:01 |
    |* 39 | TABLE ACCESS BY INDEX ROWID | TPRODUCTSKU | 1 | 33 | 1 (0)| 00:00:01 |
    |* 40 | INDEX UNIQUE SCAN | TPRODUCTSKU_PK | 1 | | 0 (0)| 00:00:01 |
    | 41 | SORT AGGREGATE | | 1 | 252 | | |
    | 42 | NESTED LOOPS | | 1 | 252 | 11 (0)| 00:00:01 |
    | 43 | NESTED LOOPS | | 1 | 240 | 10 (0)| 00:00:01 |
    | 44 | NESTED LOOPS | | 1 | 205 | 7 (0)| 00:00:01 |
    | 45 | NESTED LOOPS | | 1 | 200 | 7 (0)| 00:00:01 |
    | 46 | NESTED LOOPS | | 1 | 196 | 7 (0)| 00:00:01 |
    | 47 | NESTED LOOPS | | 1 | 191 | 7 (0)| 00:00:01 |
    | 48 | NESTED LOOPS | | 1 | 187 | 7 (0)| 00:00:01 |
    | 49 | NESTED LOOPS | | 1 | 183 | 7 (0)| 00:00:01 |
    | 50 | NESTED LOOPS | | 1 | 150 | 6 (0)| 00:00:01 |
    | 51 | NESTED LOOPS | | 1 | 120 | 5 (0)| 00:00:01 |
    | 52 | NESTED LOOPS | | 1 | 90 | 4 (0)| 00:00:01 |
    | 53 | NESTED LOOPS | | 1 | 60 | 3 (0)| 00:00:01 |
    | 54 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 30 | 2 (0)| 00:00:01 |
    |* 55 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 1 (0)| 00:00:01 |
    | 56 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 30 | 1 (0)| 00:00:01 |
    |* 57 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 58 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 30 | 1 (0)| 00:00:01 |
    |* 59 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 60 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 30 | 1 (0)| 00:00:01 |
    |* 61 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 62 | TABLE ACCESS BY INDEX ROWID | SYMMETADATA | 1 | 30 | 1 (0)| 00:00:01 |
    |* 63 | INDEX UNIQUE SCAN | SYMMETADATA_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    | 64 | TABLE ACCESS BY INDEX ROWID | TPRODUCT | 1 | 33 | 1 (0)| 00:00:01 |
    |* 65 | INDEX UNIQUE SCAN | TPRODUCT_UNIQUE | 1 | | 0 (0)| 00:00:01 |
    |* 66 | INDEX UNIQUE SCAN | SYMUSERCOUNT_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 67 | INDEX UNIQUE SCAN | SYMMEDIATYPE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 68 | INDEX UNIQUE SCAN | SYMSKUTYPE_PK | 1 | 5 | 0 (0)| 00:00:01 |
    |* 69 | INDEX UNIQUE SCAN | SYMSKULANGUAGE_PK | 1 | 4 | 0 (0)| 00:00:01 |
    |* 70 | INDEX UNIQUE SCAN | SYMVENDOR_PK | 1 | 5 | 0 (0)| 00:00:01 |
    | 71 | TABLE ACCESS BY INDEX ROWID | SYMPRODUCTSKU | 1 | 35 | 3 (0)| 00:00:01 |
    |* 72 | INDEX RANGE SCAN | I_PSKU_MERCH_LOOKUP | 1 | | 2 (0)| 00:00:01 |
    |* 73 | TABLE ACCESS BY INDEX ROWID | TPRODUCTSKU | 1 | 12 | 1 (0)| 00:00:01 |
    |* 74 | INDEX UNIQUE SCAN | TPRODUCTSKU_PK | 1 | | 0 (0)| 00:00:01 |
    Database version is 10.2.0.4. Can anyone help me understand what else to be looking for to make it work faster?

    Please see the following threads for the ideal information required:
    How to post a sql tuning request:
    HOW TO: Post a SQL statement tuning request - template posting
    When your query takes too long:
    When your query takes too long ...

  • Explain plan different for same query

    Hi all,
    I have a query, which basically selects some columns from a remote database view. The query is as follows:
    select * from tab1@remotedb, tab2@remotedb
    where tab1.cash_id = tab2.id
    and tab1.date = '01-JAN-2003'
    and tab2.country_code = 'GB';
    Now, i am working on two environments, one is production and other is development. Production environment has following specification:
    1. Remotedb = Oracle9i, Linux OS
    2. Database on which query is running = Oracle10g, Linux OS
    Development environment has following specification:
    1. Remotedb = Oracle10g, Windows OS
    2. Database on which query is running = Oracle10g, Linux OS
    Both databases in development and production environments are on different machines.
    when i execute the above query on production, i see full table scans on both tables in execution plan(TOAD), but when i execute the query in development, i see that both remote database tables are using index.
    Why am i getting different execution plans on both databases? is there is any difference of user rights/priviliges or there is a difference of statistics on both databases. I have checked the statistics for both tables on Production and Development databases, they are updated.
    This issue is creating a performance disaster in our Production system. Any kind of help or knowledge sharing is appreciated.
    Thank you and Best Regards.

    We ran into a similar situation yesterday morning, though our implementation was easier than yours. Different plans in development and production though both systems were 10gR2 at the time. Production was doing a Merge Join Cartesian (!) instead of nested loop joins. Our DBA figured out that the production stats had been locked for some tables preventing stat refresh; she unlocked them and re-analyzed so which fixed our problem.
    Of some interest was discovering that I got different execution plans from the same UPDATE via EXPLAIN PLAN and SQL*PLUS AUTOTRACE in development. Issue appears to have been bind peeking. Converting bind variables to constants yielded the AUTOTRACE plan, as did turning bind peeking off while using the bind variables. CURSOR_SHARING was set to EXACT too.
    Message was edited by:
    riedelme

  • Explain plan for Query performance

    Hi Gurus,
    I need to improve the performance of a procedure. The procedure has the below QUery. I dont have Idea on how to imrpove the perf by seeing the explain plan. Can anyone please help me to explain where I need to change the code.
    The below are the code and Explain plan for the same.
    -----------Code----------------------------
    SELECT IV_STORECODE AS STORECODE,
                                   TO_CHAR(RD.ITEMCODE) AS ITEMCODE,
                                   C.ITEMCATEGORYNAME,
                                   ISUB.ITEMSUBCATEGORY1NAME
                              FROM RECEIPTS R
                             INNER JOIN RECEIPTDETAILS RD
                                ON R.RECEIPTID = RD.RECEIPTID
                             INNER JOIN ITEMCOMPANY IC
                                ON IC.ITEMCODE = RD.ITEMCODE
                             INNER JOIN ITEMCATEGORY C
                                ON IC.ITEMCATEGORY = C.ITEMCATEGORYID
                             LEFT OUTER JOIN ITEMSUBCATEGORY1 ISUB
                                ON ISUB.ITEMSUBCATEGORY1ID = IC.ITEMSUBCATEGORY1
                               AND ISUB.ITEMSUBCATEGORY1ID IN
                                   (SELECT ITEMSUBCATEGORY1ID
                                      FROM ITEMSUBCATEGORY1
                                     WHERE ITEMCATEGORYID = IV_ITEMCATEGORY)
                             INNER JOIN STORE SE
                                ON SE.STORECODE = R.STORECODE
                             WHERE R.STORECODE = IV_STORECODE
                               AND SE.HOSPITALID = IV_HOSPITALID
                               AND TRUNC(R.CREATEDDATE) BETWEEN V_FROMDATE AND
                                   V_TODATE
                               AND R.STATUSID NOT IN (99, 5)
                                  AND
                                   (IV_DRUGTYPE IS NULL OR
                                   IC.DRUGTYPECATEGORYID = IV_DRUGTYPE)
                            UNION
                            SELECT IV_STORECODE AS STORECODE,
                                   TO_CHAR(STD.ITEMCODE) AS ITEMCODE,
                                   C.ITEMCATEGORYNAME,
                                   ISUB.ITEMSUBCATEGORY1NAME
                              FROM STOCKTRANSACTION ST
                             INNER JOIN STOCKTRANSACTIONDETAILS STD
                                ON ST.STOCKTRANSACTIONID = STD.STOCKTRANSACTIONID
                             INNER JOIN ITEMCOMPANY IC
                                ON IC.ITEMCODE = STD.ITEMCODE
                             INNER JOIN ITEMCATEGORY C
                                ON IC.ITEMCATEGORY = C.ITEMCATEGORYID
                              LEFT OUTER JOIN ITEMSUBCATEGORY1 ISUB
                                ON ISUB.ITEMSUBCATEGORY1ID = IC.ITEMSUBCATEGORY1
                               AND ISUB.ITEMSUBCATEGORY1ID IN
                                   (SELECT ITEMSUBCATEGORY1ID
                                      FROM ITEMSUBCATEGORY1
                                     WHERE ITEMCATEGORYID = IV_ITEMCATEGORY)
                             INNER JOIN STORE SE
                                ON SE.STORECODE = ST.STORECODE
                             WHERE ST.STORECODE = IV_STORECODE
                               AND SE.HOSPITALID = IV_HOSPITALID
                               AND TRUNC(ST.CREATEDDATE) BETWEEN V_FROMDATE AND
                                   V_TODATE
                               AND ST.STATUS <> 99
                               AND STD.ITEMCODE NOT LIKE '%#%'
                               AND                   
                                   (IV_DRUGTYPE IS NULL OR
                                   IC.DRUGTYPECATEGORYID = IV_DRUGTYPE)
                            UNION
                            SELECT D.STORECODE,
                                   TO_CHAR(D.ITEMCODE) AS ITEMCODE,
                                   C.ITEMCATEGORYNAME,
                                   ISUB.ITEMSUBCATEGORY1NAME
                              FROM DAILYINVENTORY D
                             INNER JOIN ITEMCOMPANY IC
                                ON IC.ITEMCODE = D.ITEMCODE
                             INNER JOIN ITEMCATEGORY C
                                ON IC.ITEMCATEGORY = C.ITEMCATEGORYID
                              LEFT OUTER JOIN ITEMSUBCATEGORY1 ISUB
                                ON ISUB.ITEMSUBCATEGORY1ID = IC.ITEMSUBCATEGORY1
                               AND ISUB.ITEMSUBCATEGORY1ID IN
                                   (SELECT ITEMSUBCATEGORY1ID
                                      FROM ITEMSUBCATEGORY1
                                     WHERE ITEMCATEGORYID = IV_ITEMCATEGORY)
                             INNER JOIN STORE SE
                                ON SE.STORECODE = D.STORECODE
                             WHERE D.STORECODE = IV_STORECODE
                               AND SE.HOSPITALID = IV_HOSPITALID
                               AND TRUNC(D.UPDATEDDATE) <= V_TODATE
                               AND D.QTY > 0
                               AND D.ITEMCODE NOT LIKE '%#%'
                               AND C.ITEMCATEGORYID = IV_ITEMCATEGORY
                                  AND (IV_DRUGTYPE IS NULL OR
                                   IC.DRUGTYPECATEGORYID = IV_DRUGTYPE)
                               AND (IV_SUBITEMCATEGORY IS NULL OR
                                   ISUB.ITEMSUBCATEGORY1ID = IV_SUBITEMCATEGORY) Will post the explain plan ..
    Thanks in advance..

    Ensure you also include all the other information people will need to help you, e.g. database version, table structures/relationships and cardinalities, row counts etc.
    See the two threads linked to in the FAQ: {message:id=9360003}

Maybe you are looking for