Oracle Query Tuning

Hi,
I am having difficulty with a particular issue. We have a column that is indexed, but we are looking just for the NULL columns and it is deciding to do a full table scan.
Here is the query and the output from the explain plan. Much of our cost is spent on step 11 below.
Thanks : )
SELECT          SEVERITY.SEVERITY_CODE,
                         ACCOUNT.ACCOUNT_NUMBER,
                         ACTIVITY.BLOCK_TYPE_ID,
                         ACTIVITY_ACCOUNT.ERROR_MSG,
                         DECODE(ACTIVITY.REISSUE_IND,0,NULL,ACTIVITY.REISSUE_IND) AS REISSUE_IND,
                         ACTIVITY_ACCOUNT.REPLACE_ACCOUNT_NUMBER,
                         ACTIVITY_ACCOUNT.EXP_DATE_OVERRIDE,
                         ACTIVITY.SCHEDULED_BLOCK_DATE,
                         ACTIVITY.EWB_REGION_CODES,
                         ACTIVITY.EWB_PURGE_DATE,
                         ACTIVITY.LETTER_TYPE,
                         ACTIVITY.LETTER_ID,
                         DECODE(ACTIVITY.DIALER_IND,0,NULL,ACTIVITY.DIALER_IND) AS DIALER_IND,
                         DECODE(ACTIVITY.RUSH_PLASTIC_IND,0,NULL,ACTIVITY.RUSH_PLASTIC_IND) AS RUSH_PLASTIC_IND,
                         ALERT.ALERT_EVENT,
                         ACTIVITY.ACTIVITY_DATE,
                         ACTIVITY_ACCOUNT.BLOCK_RECLASS_CODE,
                         ACCOUNT.CORP
               FROM          ACTIVITY
               INNER JOIN     ALERT ON ACTIVITY.ALERT_ID = ALERT.ALERT_ID
               INNER JOIN     SEVERITY ON ALERT.SEVERITY_ID = SEVERITY.SEVERITY_ID
               INNER JOIN     ACTIVITY_ACCOUNT ON ACTIVITY.ACTIVITY_ID = ACTIVITY_ACCOUNT.ACTIVITY_ID
               INNER JOIN     ACCOUNT ON ACTIVITY_ACCOUNT.ACCOUNT_ID = ACCOUNT.ACCOUNT_ID
               WHERE          ACTIVITY_DATE < SYSDATE AND
                              STATUS_ID <> 3 AND                    --3 is DELETED
                    UPLOADED_DATE IS NULL AND
                              ACCOUNT.HOST_SYSTEM_ID = 'P';
38668 rows selected.
Execution Plan
Plan hash value: 409974871
| Id  | Operation                       | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT                |                  | 17367 |  2849K|   479   (4)| 00:00:06 |
|*  1 |  HASH JOIN                      |                  | 17367 |  2849K|   479   (4)| 00:00:06 |
|*  2 |   TABLE ACCESS FULL             | ACCOUNT          |  5705 |   172K|    56   (2)| 00:00:01 |
|*  3 |   HASH JOIN                     |                  | 42728 |  5716K|   422   (4)| 00:00:06 |
|*  4 |    HASH JOIN                    |                  |   153 | 17136 |    10  (20)| 00:00:01 |
|   5 |     MERGE JOIN                  |                  |   116 |  6496 |     6  (17)| 00:00:01 |
|   6 |      TABLE ACCESS BY INDEX ROWID| SEVERITY         |     2 |    12 |     2   (0)| 00:00:01 |
|   7 |       INDEX FULL SCAN           | PK_SEVERITY      |     2 |       |     1   (0)| 00:00:01 |
|*  8 |      SORT JOIN                  |                  |   116 |  5800 |     4  (25)| 00:00:01 |
|   9 |       TABLE ACCESS FULL         | ALERT            |   116 |  5800 |     3   (0)| 00:00:01 |
|* 10 |     TABLE ACCESS FULL           | ACTIVITY         |   153 |  8568 |     3   (0)| 00:00:01 |
|* 11 |    TABLE ACCESS FULL            | ACTIVITY_ACCOUNT | 42868 |  1046K|   412   (4)| 00:00:05 |
Predicate Information (identified by operation id):
   1 - access("ACTIVITY_ACCOUNT"."ACCOUNT_ID"="ACCOUNT"."ACCOUNT_ID")
   2 - filter("ACCOUNT"."HOST_SYSTEM_ID"='P')
   3 - access("ACTIVITY"."ACTIVITY_ID"="ACTIVITY_ACCOUNT"."ACTIVITY_ID")
   4 - access("ACTIVITY"."ALERT_ID"="ALERT"."ALERT_ID")
   8 - access("ALERT"."SEVERITY_ID"="SEVERITY"."SEVERITY_ID")
       filter("ALERT"."SEVERITY_ID"="SEVERITY"."SEVERITY_ID")
  10 - filter("ACTIVITY"."STATUS_ID"<>3 AND "ACTIVITY"."ACTIVITY_DATE"<SYSDATE@!)
  11 - filter("ACTIVITY_ACCOUNT"."UPLOADED_DATE" IS NULL)
Statistics
          0  recursive calls
          0  db block gets
       4633  consistent gets
          0  physical reads
          0  redo size
    3111385  bytes sent via SQL*Net to client
      18277  bytes received via SQL*Net from client
       2579  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      38668  rows processedAs you see, Step 11 is doing a full table scan. Should I be using a different index besides the standard B Tree?

A B-tree index will not contain references to NULL values in an index because NULL compared to any other value is always false, even if that other "value" is NULL (strictly speaking, NULL isn't a value at all).
A bitmap index will, however, have a bitmap for NULL. Whether or not a bitmap index is useful on that particular column is another story. But you did ask so I felt compelled to answer.
If a bitmap index is inappropriate, consider a function-based index where you turn the NULLs into something useful. For instance, if you build a function-based index on
CASE WHEN some_col IS NULL THEN 1 ELSE 0 END
you might be able to put the same syntax in your where clause and experience the performance you need.

Similar Messages

  • Oracle query tuning : query with Order-by clause

    Hi
    I am having a query in my database :
    SELECT * FROM SAPR3.HRP1001 WHERE "MANDT" = 990
    ORDER BY
    "MANDT" , "OTYPE" , "OBJID" , "PLVAR" , "RSIGN" , "RELAT" , "ISTAT" , "PRIOX" , "BEGDA" , "ENDDA" ,"VARYF" , "SEQNR" ;
    Autotrace output is :
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4649 Card=171895 Byt
    es=22862035)
    1 0 SORT (ORDER BY) (Cost=4649 Card=171895 Bytes=22862035)
    2 1 TABLE ACCESS (FULL) OF 'HRP1001' (Cost=1170 Card=171895
    Bytes=22862035)
    Statistics
    0 recursive calls
    5 db block gets
    12157 consistent gets
    11543 physical reads
    0 redo size
    38253080 bytes sent via SQL*Net to client
    376841 bytes received via SQL*Net from client
    34201 SQL*Net roundtrips to/from client
    0 sorts (memory)
    1 sorts (disk)
    512992 rows processed
    Since it is a issue with order by , it seems a PGA memory issue. there is 12GB PGA available but only 3GB gets allocated. pga_aggregate target is set in the DB. There is a index created for al the columns on order by, but it is not getting used.
    pleas suggest me as I am running into major problems, i can post the output of any query u require from my side. Any help wil be highly apprciated.
    Rishi

    > The query was alwasy spilling over to the One-Parse execution . It can be seen thru ST04N ->resource consumption-> sql work area trace.
    >
    > An undocumented oracle parameter smmmax_size was set which allowed for more usage of physical memory by single process and there was no spillover to the TEMP tablespaces.
    >
    > Also the File read time was analysed from Unix level ( From SAP thru ST04 ->filesystem wait s-> Avg rd (ms) and Ang writes (ms) which showed that reading from the File was not happening well. )
    Hi Rishi,
    the provided execution statistics prove the opposite:
    >Statistics
    >...
    >0 sorts (memory)
    > 1 sorts (disk)
    >512992 rows processed
    This indeed was a single-pass sort, which means it had to use the temp tablespace for one pass of the sorting/grouping.
    Remember that Oracle distinguishes three kinds of sorts: 1. "in memory", 2. "single-pass" and 3. "multi-pass".
    Only the first one won't need to spill out data to the disks. The others do this by definition.
    BTW: the file read times in ST04 are aquired through Oracle V$ views and not directly from the OS - that can make a big difference sometimes.
    regards,
    Lars

  • Help for query tuning

    hello all
    my one of query is returning result in 1-2 mins only for 1 lakh record but i am not sure if it showed me complete rows or not because when I an trying to get count of result ..its taking lot of time .when I am using this query on plsql code ..code is running slow so just wanted to confirm on query tuning point of view if its fine or not ..please look onto it and let me know if query is fine or not by explain plan .my oracle version is 11g
    this is my query
    SELECT ROWNUM , TRUNC(rownum/5000) + 20000 ,'FOR_UPDATE', sku_org.NAME ,
    acct_promo_sku.src_num , acct_promo_sku.sub_type ,
    promo_actual.sku_actual_pos
    FROM siebel.s_src acct_promo_hdr,
    siebel.s_src acct_title_format,
    siebel.s_src acct_promo_sku,
    siebel.s_src_x acct_promo_hdrx,
    siebel.s_src_x acct_promo_skux,
    siebel.s_prod_int prod,
    siebel.s_bu promo_hdr_org,
    siebel.s_bu sku_org,
    siebelwb.stg_sbl_acct_promo_actuals2 promo_actual
    WHERE acct_promo_hdr.sub_type = 'PLAN_ACCOUNT_PROMOTION'
    AND acct_promo_hdr.row_id = acct_title_format.par_src_id
    AND acct_title_format.sub_type = 'PLAN_ACCT_PROMOTION_CATEGORY'
    AND acct_title_format.row_id = acct_promo_sku.par_src_id
    AND acct_promo_sku.sub_type = 'PLAN_ACCOUNT_PROMOTION_PRODUCT'
    AND acct_promo_hdr.row_id = acct_promo_hdrx.par_row_id
    AND acct_promo_sku.row_id = acct_promo_skux.par_row_id(+)
    AND acct_promo_sku.prod_id = prod.row_id
    AND acct_promo_hdr.bu_id = promo_hdr_org.row_id
    AND acct_promo_sku.bu_id = sku_org.row_id
    AND prod.x_prod_material_num = promo_actual.material_number
    and prod.X_PROD_SALES_ORG=promo_actual.sales_org
    AND acct_promo_hdr.row_id = promo_actual.acct_promo_id
    and nvl(acct_promo_hdr.pr_accnt_id,0)=nvl(promo_actual.acct_siebel_rowid,0)
    and nvl(acct_promo_hdr.x_indirect_id,0)=nvl(promo_actual.indirect_acct_siebel_rowid,0)
    AND promo_actual.load_date >= TRUNC(SYSDATE)
    AND promo_actual.load_date < TRUNC(SYSDATE + 1)
    explain plan
    PLAN_TABLE_OUTPUT
    Plan hash value: 3864590768
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 298 | 2300 (1)| 00:00:28 |
    | 1 | COUNT | | | | | |
    |* 2 | FILTER | | | | | |
    | 3 | NESTED LOOPS | | | | | |
    | 4 | NESTED LOOPS | | 1 | 298 | 2300 (1)| 00:00:28 |
    | 5 | NESTED LOOPS OUTER | | 1 | 273 | 2298 (1)| 00:00:28 |
    | 6 | NESTED LOOPS | | 1 | 263 | 2296 (1)| 00:00:28 |
    | 7 | NESTED LOOPS | | 1 | 236 | 2295 (1)| 00:00:28 |
    | 8 | NESTED LOOPS | | 1 | 165 | 2292 (1)| 00:00:28 |
    | 9 | NESTED LOOPS | | 1 | 117 | 2289 (1)| 00:00:28 |
    | 10 | NESTED LOOPS | | 1 | 109 | 2289 (1)| 00:00:28 |
    | 11 | NESTED LOOPS | | 1 | 99 | 2287 (1)| 00:00:28 |
    |* 12 | TABLE ACCESS FULL | STG_SBL_ACCT_PROMO_ACTUALS2 | 1 | 49 | 2285 (1)| 00:0
    |* 13 | TABLE ACCESS BY INDEX ROWID| S_SRC | 1 | 50 | 2 (0)| 00:00:01 |
    |* 14 | INDEX UNIQUE SCAN | S_SRC_P1 | 1 | | 1 (0)| 00:00:01 |
    |* 15 | INDEX RANGE SCAN | S_SRC_X_U1 | 1 | 10 | 2 (0)| 00:00:01 |
    |* 16 | INDEX UNIQUE SCAN | S_BU_P1 | 1 | 8 | 0 (0)| 00:00:01 |
    |* 17 | TABLE ACCESS BY INDEX ROWID | S_SRC | 1 | 48 | 3 (0)| 00:00:01 |
    |* 18 | INDEX RANGE SCAN | S_SRC_F2 | 2 | | 2 (0)| 00:00:01 |
    |* 19 | TABLE ACCESS BY INDEX ROWID | S_SRC | 1 | 71 | 3 (0)| 00:00:01 |
    |* 20 | INDEX RANGE SCAN | S_SRC_F2 | 2 | | 2 (0)| 00:00:01 |
    | 21 | TABLE ACCESS BY INDEX ROWID | S_BU | 1 | 27 | 1 (0)| 00:00:01 |
    |* 22 | INDEX UNIQUE SCAN | S_BU_P1 | 1 | | 0 (0)| 00:00:01 |
    |* 23 | INDEX RANGE SCAN | S_SRC_X_U1 | 1 | 10 | 2 (0)| 00:00:01 |
    |* 24 | INDEX UNIQUE SCAN | S_PROD_INT_P1 | 1 | | 1 (0)| 00:00:01 |
    |* 25 | TABLE ACCESS BY INDEX ROWID | S_PROD_INT | 1 | 25 | 2 (0)| 00:00:
    Predicate Information (identified by operation id):
    2 - filter(TRUNC(SYSDATE@!)<TRUNC(SYSDATE@!+1))
    12 - filter("PROMO_ACTUAL"."LOAD_DATE">=TRUNC(SYSDATE@!) AND "PROMO_ACTUAL"."LOAD_DATE"<TRUNC(SYSD
    13 - filter("ACCT_PROMO_HDR"."SUB_TYPE"='PLAN_ACCOUNT_PROMOTION' AND
    NVL("ACCT_PROMO_HDR"."PR_ACCNT_ID",'0')=NVL("PROMO_ACTUAL"."ACCT_SIEBEL_ROWID",'0') AND
    NVL("ACCT_PROMO_HDR"."X_INDIRECT_ID",'0')=NVL("PROMO_ACTUAL"."INDIRECT_ACCT_SIEBEL_ROWID",'0'
    14 - access("ACCT_PROMO_HDR"."ROW_ID"="PROMO_ACTUAL"."ACCT_PROMO_ID")
    15 - access("ACCT_PROMO_HDR"."ROW_ID"="ACCT_PROMO_HDRX"."PAR_ROW_ID")
    16 - access("ACCT_PROMO_HDR"."BU_ID"="PROMO_HDR_ORG"."ROW_ID")
    17 - filter("ACCT_TITLE_FORMAT"."SUB_TYPE"='PLAN_ACCT_PROMOTION_CATEGORY')
    18 - access("ACCT_PROMO_HDR"."ROW_ID"="ACCT_TITLE_FORMAT"."PAR_SRC_ID")
    19 - filter("ACCT_PROMO_SKU"."PROD_ID" IS NOT NULL AND
    "ACCT_PROMO_SKU"."SUB_TYPE"='PLAN_ACCOUNT_PROMOTION_PRODUCT')
    20 - access("ACCT_TITLE_FORMAT"."ROW_ID"="ACCT_PROMO_SKU"."PAR_SRC_ID")
    22 - access("ACCT_PROMO_SKU"."BU_ID"="SKU_ORG"."ROW_ID")
    23 - access("ACCT_PROMO_SKU"."ROW_ID"="ACCT_PROMO_SKUX"."PAR_ROW_ID"(+))
    24 - access("ACCT_PROMO_SKU"."PROD_ID"="PROD"."ROW_ID")
    25 - filter("PROD"."X_PROD_MATERIAL_NUM" IS NOT NULL AND
    "PROD"."X_PROD_MATERIAL_NUM"="PROMO_ACTUAL"."MATERIAL_NUMBER" AND
    "PROD"."X_PROD_SALES_ORG"="PROMO_ACTUAL"."SALES_ORG")
    55 rows selected.
    thanks

    Hi,
    the plan you posted has the cost of 2300, i.e. 2300 single-block reads or equivalent number f multi-block reads. Even if none of the blocks is found in cache, 2300 reas shouldn't take more than a couple of minutes, beacause for most of the hard drives available today a disk read is typically within 5-10 ms.
    This means that if there is a problem, we will never find out about it by looking in the plan. And it's quite likely that there is, in fact, a problem, because the plan contains a bunch of nested joins, and the cost of each nested join is directly proportional to the cardinality of the previous nested loop. I.e. it suffices to make one bad mistake in estimating the number of rows coming fom one of the nested rows to screw up the entire plan and get all remaining estimates (including the total cost of the query) completely wrong.
    In order for us to be able to tell more, we need to see the plan with rowsource statistics, and please don't forget to use tags to preserve formatting (use the preview tab to make sure the posted plan is actually readable).
    Best regards,
      Nikolay                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Query tuning request

    This is my first post in this forum regarding query tuning, so my sincere apologies in advance if I have:
    1) not included sufficient information,
    2) included too much information,
    3) not posted to the correct forum
    I read through Randolf Geist's web page on instructions to post a query tuning request
    and attempted to follow it as closely as possible.
    I am attempting to figure out where a view I have constructed can be optimized.
    It takes approx. 45 seconds to 1 minute to run; I would like to cut that down to 10 seconds if possible.
    The view itself is somewhat complex; I will post the actual code if it will help you help me. Please advise.
    I was under the impression that posting the code was not necessary, but if it is, let me know and I will post it.
    I have been doing SQL development for a few years, but only recently in Oracle.
    I have no experience in looking through the following output and being able to tell where I can improve performance,
    so this will be a learning experience for me. Thanks in advance for your help - I appreciate it.
    Some additional information - my view is based on tables over which I have no control - it is a third-party application
    which I do reporting from. I do have the freedom to create indexes on columns within the tables if necessary.
    The statement is simply
    SELECT * FROM LLU_V_PRODUCTION_DETAIL_03
    which is the name of my view.
    here's all the information I've been able to retrieve by following Randolf's instructions:
    Oracle version is 10.2.0.1.0 - 64bit
    Here are optimizer parameters:
    NAME                                 TYPE        VALUE
    user_dump_dest                       string      C:\ORACLE\PRODUCT\10.2.0\ADMIN
                                                     \AXIUMPRODUCTION\UDUMP
    NAME                                 TYPE        VALUE
    optimizer_dynamic_sampling           integer     2
    optimizer_features_enable            string      10.2.0.1
    optimizer_index_caching              integer     90
    optimizer_index_cost_adj             integer     20
    optimizer_mode                       string      ALL_ROWS
    optimizer_secure_view_merging        boolean     TRUE
    NAME                                 TYPE        VALUE
    db_file_multiblock_read_count        integer     16
    NAME                                 TYPE        VALUE
    db_block_size                        integer     8192
    NAME                                 TYPE        VALUE
    cursor_sharing                       string      EXACT
    SNAME                PNAME                     PVAL1 PVAL2
    SYSSTATS_INFO        STATUS                          COMPLETED
    SYSSTATS_INFO        DSTART                          10-29-2005 01:36
    SYSSTATS_INFO        DSTOP                           10-29-2005 01:36
    SYSSTATS_INFO        FLAGS                         1
    SYSSTATS_MAIN        CPUSPEEDNW           1298.56584
    SYSSTATS_MAIN        IOSEEKTIM                    10
    SYSSTATS_MAIN        IOTFRSPEED                 4096
    SYSSTATS_MAIN        SREADTIM
    SYSSTATS_MAIN        MREADTIM
    SYSSTATS_MAIN        CPUSPEED
    SYSSTATS_MAIN        MBRC
    SYSSTATS_MAIN        MAXTHR
    SYSSTATS_MAIN        SLAVETHR
    13 rows selected.Here is the output of EXPLAIN PLAN:
    PLAN_TABLE_OUTPUT
    Plan hash value: 662813077
    | Id  | Operation                              | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                       |                             |    23M|    53G|       | 62330   (2)| 00:12:28 |
    |   1 |  VIEW                                  | LLU_V_PRODUCTION_DETAIL_03  |    23M|    53G|       | 62330   (2)| 00:12:28 |
    |   2 |   UNION-ALL                            |                             |       |       |       |            |          |
    |*  3 |    HASH JOIN                           |                             |    18M|  5062M|       |  1525  (10)| 00:00:19 |
    |   4 |     VIEW                               | index$_join$_007            |  1725 | 25875 |       |     4  (25)| 00:00:01 |
    |*  5 |      HASH JOIN                         |                             |       |       |       |            |          |
    |   6 |       INDEX FAST FULL SCAN             | USERS_PRIMARY               |  1725 | 25875 |       |     1   (0)| 00:00:01 |
    |   7 |       INDEX FAST FULL SCAN             | USERS_PRODUCER              |  1725 | 25875 |       |     2   (0)| 00:00:01 |
    |*  8 |     HASH JOIN                          |                             |   416K|   105M|       |  1399   (2)| 00:00:17 |
    |   9 |      TABLE ACCESS FULL                 | PRODUCER                    |  1396 |   118K|       |    24   (0)| 00:00:01 |
    |* 10 |      HASH JOIN                         |                             | 29819 |  5183K|       |  1372   (2)| 00:00:17 |
    |  11 |       TABLE ACCESS FULL                | CLASS                       |    20 |  1660 |       |     3   (0)| 00:00:01 |
    |* 12 |       TABLE ACCESS FULL                | QR_PRODUCTION               |   149K|    13M|       |  1367   (2)| 00:00:17 |
    |* 13 |    FILTER                              |                             |       |       |       |            |          |
    |* 14 |     HASH JOIN                          |                             |    16M|  5651M|       | 32983   (2)| 00:06:36 |
    |  15 |      VIEW                              | index$_join$_014            |  1725 | 25875 |       |     4  (25)| 00:00:01 |
    |* 16 |       HASH JOIN                        |                             |       |       |       |            |          |
    |  17 |        INDEX FAST FULL SCAN            | USERS_PRIMARY               |  1725 | 25875 |       |     1   (0)| 00:00:01 |
    |  18 |        INDEX FAST FULL SCAN            | USERS_PRODUCER              |  1725 | 25875 |       |     2   (0)| 00:00:01 |
    |* 19 |      HASH JOIN                         |                             |   149K|    49M|       | 32874   (1)| 00:06:35 |
    |  20 |       TABLE ACCESS FULL                | CLASS                       |    20 |  1660 |       |     3   (0)| 00:00:01 |
    |* 21 |       HASH JOIN                        |                             |   149K|    37M|       | 32870   (1)| 00:06:35 |
    |  22 |        TABLE ACCESS FULL               | PRODUCER                    |  1396 |   118K|       |    24   (0)| 00:00:01 |
    |* 23 |        HASH JOIN                       |                             |   222K|    37M|    12M| 32844   (1)| 00:06:35 |
    |  24 |         TABLE ACCESS FULL              | PATIENT                     |   188K|    10M|       |  6979   (1)| 00:01:24 |
    |* 25 |         HASH JOIN                      |                             |   222K|    24M|       | 23860   (2)| 00:04:47 |
    |* 26 |          TABLE ACCESS FULL             | PROCEDUR                    |   888 | 44400 |       |    11   (0)| 00:00:01 |
    |* 27 |          TABLE ACCESS FULL             | TRX                         |   442K|    28M|       | 23845   (2)| 00:04:47 |
    |* 28 |     TABLE ACCESS FULL                  | USERS                       |     1 |    11 |       |    55   (0)| 00:00:01 |
    |  29 |    NESTED LOOPS                        |                             |     1 |   473 |       | 25798   (1)| 00:05:10 |
    |  30 |     NESTED LOOPS                       |                             |     1 |   413 |       | 25797   (1)| 00:05:10 |
    |  31 |      NESTED LOOPS                      |                             |     1 |   398 |       | 25796   (1)| 00:05:10 |
    |  32 |       NESTED LOOPS                     |                             |     1 |   390 |       | 25795   (1)| 00:05:10 |
    |* 33 |        HASH JOIN                       |                             |     1 |   303 |       | 25794   (1)| 00:05:10 |
    |  34 |         TABLE ACCESS FULL              | LLU_EVALUATION_DESCRIPTIONS |    95 |  6175 |       |     3   (0)| 00:00:01 |
    |* 35 |         HASH JOIN                      |                             |  4630 |  1076K|       | 25791   (1)| 00:05:10 |
    |* 36 |          HASH JOIN                     |                             |  9607 |  1623K|       | 23834   (1)| 00:04:47 |
    |  37 |           MERGE JOIN                   |                             |   888 | 91464 |       |    13   (8)| 00:00:01 |
    |  38 |            TABLE ACCESS BY INDEX ROWID | CLASS                       |    20 |  1660 |       |     1   (0)| 00:00:01 |
    |  39 |             INDEX FULL SCAN            | CLASS_PRIMARY               |    20 |       |       |     1   (0)| 00:00:01 |
    |* 40 |            SORT JOIN                   |                             |   888 | 17760 |       |    12   (9)| 00:00:01 |
    |* 41 |             TABLE ACCESS FULL          | PROCEDUR                    |   888 | 17760 |       |    11   (0)| 00:00:01 |
    |* 42 |           TABLE ACCESS FULL            | TRX                         | 19125 |  1307K|       | 23820   (1)| 00:04:46 |
    |* 43 |          TABLE ACCESS FULL             | GRADITEM                    |   655K|    40M|       |  1952   (1)| 00:00:24 |
    |  44 |        TABLE ACCESS BY INDEX ROWID     | PRODUCER                    |     1 |    87 |       |     1   (0)| 00:00:01 |
    |* 45 |         INDEX UNIQUE SCAN              | PRODUCER_PRIMARY            |     1 |       |       |     1   (0)| 00:00:01 |
    |* 46 |       TABLE ACCESS BY INDEX ROWID      | GRADING                     |     1 |     8 |       |     1   (0)| 00:00:01 |
    |* 47 |        INDEX UNIQUE SCAN               | GRADING_PRIMARY             |     1 |       |       |     1   (0)| 00:00:01 |
    |  48 |      TABLE ACCESS BY INDEX ROWID       | USERS                       |   221 |  3315 |       |     1   (0)| 00:00:01 |
    |* 49 |       INDEX RANGE SCAN                 | USERS_PRODUCER              |     1 |       |       |     1   (0)| 00:00:01 |
    |  50 |     TABLE ACCESS BY INDEX ROWID        | PATIENT                     |     1 |    60 |       |     1   (0)| 00:00:01 |
    |* 51 |      INDEX UNIQUE SCAN                 | PATIENT_PRIMARY             |     1 |       |       |     1   (0)| 00:00:01 |
    |  52 |    TABLE ACCESS BY INDEX ROWID         | USERS                       |   109 |  1635 |       |     1   (0)| 00:00:01 |
    |  53 |     NESTED LOOPS                       |                             |     1 |   438 |       |  2023   (1)| 00:00:25 |
    |  54 |      NESTED LOOPS                      |                             |     1 |   423 |       |  2022   (1)| 00:00:25 |
    |  55 |       NESTED LOOPS                     |                             |     1 |   363 |       |  2021   (1)| 00:00:25 |
    |  56 |        NESTED LOOPS                    |                             |     1 |   276 |       |  2020   (1)| 00:00:25 |
    |  57 |         NESTED LOOPS                   |                             |     1 |   193 |       |  2019   (1)| 00:00:25 |
    |  58 |          NESTED LOOPS                  |                             |     1 |   185 |       |  2018   (1)| 00:00:25 |
    |  59 |           NESTED LOOPS                 |                             |     1 |   173 |       |  2017   (1)| 00:00:25 |
    |  60 |            NESTED LOOPS                |                             |     1 |   140 |       |  2016   (1)| 00:00:25 |
    |* 61 |             TABLE ACCESS FULL          | GRADITEM                    |   317 | 23141 |       |  1953   (2)| 00:00:24 |
    |* 62 |             TABLE ACCESS BY INDEX ROWID| TRX                         |     1 |    67 |       |     1   (0)| 00:00:01 |
    |* 63 |              INDEX UNIQUE SCAN         | TRX_PRIMARY                 |     1 |       |       |     1   (0)| 00:00:01 |
    |* 64 |            TABLE ACCESS BY INDEX ROWID | TRX                         |     1 |    33 |       |     1   (0)| 00:00:01 |
    |* 65 |             INDEX UNIQUE SCAN          | TRX_PRIMARY                 |     1 |       |       |     1   (0)| 00:00:01 |
    |* 66 |           TABLE ACCESS BY INDEX ROWID  | GRADITEM                    |     1 |    12 |       |     1   (0)| 00:00:01 |
    |* 67 |            INDEX RANGE SCAN            | GRADITEM_ID                 |    19 |       |       |     1   (0)| 00:00:01 |
    |* 68 |          TABLE ACCESS BY INDEX ROWID   | GRADING                     |     1 |     8 |       |     1   (0)| 00:00:01 |
    |* 69 |           INDEX UNIQUE SCAN            | GRADING_PRIMARY             |     1 |       |       |     1   (0)| 00:00:01 |
    |  70 |         TABLE ACCESS BY INDEX ROWID    | CLASS                       |     1 |    83 |       |     1   (0)| 00:00:01 |
    |* 71 |          INDEX UNIQUE SCAN             | CLASS_PRIMARY               |     1 |       |       |     1   (0)| 00:00:01 |
    |  72 |        TABLE ACCESS BY INDEX ROWID     | PRODUCER                    |     1 |    87 |       |     1   (0)| 00:00:01 |
    |* 73 |         INDEX UNIQUE SCAN              | PRODUCER_PRIMARY            |     1 |       |       |     1   (0)| 00:00:01 |
    |  74 |       TABLE ACCESS BY INDEX ROWID      | PATIENT                     |     1 |    60 |       |     1   (0)| 00:00:01 |
    |* 75 |        INDEX UNIQUE SCAN               | PATIENT_PRIMARY             |     1 |       |       |     1   (0)| 00:00:01 |
    |* 76 |      INDEX RANGE SCAN                  | USERS_PRODUCER              |     1 |       |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - access("QRP"."ProviderID"="U1"."Producer")
       5 - access(ROWID=ROWID)
       8 - access(TRIM("QRP"."ProviderID")=TRIM("P"."Producer"))
      10 - access(TRIM("QRP"."axiUm_Discipline")=TRIM("CLASS"."Class"))
      12 - filter("QRP"."ProviderID" IS NOT NULL AND "QRP"."Location"<'9990' AND "QRP"."ProcedureID"<>185 AND
                  "QRP"."PatientFirstName"<>'NON-PATIENT' AND ("QRP"."PatientFirstName"<>'TED' OR "QRP"."PatientLastName" NOT LIKE
                  'CAVENDER%'))
      13 - filter( NOT EXISTS (SELECT 0 FROM AXIUM."USERS" "USERS" WHERE "Custom3"='YES' AND LNNVL("User"<>:B1)) OR
                  TO_CHAR(INTERNAL_FUNCTION("P"."EndDate"),'YYYY')<'2011' OR TRIM(TO_CHAR(INTERNAL_FUNCTION("P"."EndDate"),'YYYY')) IS
                  NULL OR "TRX"."Procedure"='A0021' OR "TRX"."Procedure"='A0022')
      14 - access("TRX"."Producer"="U1"."Producer")
      16 - access(ROWID=ROWID)
      19 - access("PROC"."Discipline"="CLASS"."Class")
      21 - access("TRX"."Producer"="P"."Producer")
      23 - access("TRX"."Patient"="PAT"."Patient")
      25 - access("TRX"."Procedure"="PROC"."Procedure")
      26 - filter("PROC"."Discipline" IS NOT NULL)
      27 - filter("TRX"."Deleted"=0 AND "TRX"."Status"='C' AND "TRX"."Procedure" NOT LIKE 'D0149%' AND
                  "TRX"."Procedure"<>'D5001C')
      28 - filter("Custom3"='YES' AND LNNVL("User"<>:B1))
      33 - access(TRIM(UPPER("GI"."QuestionText"))=TRIM(UPPER("LLU"."GRADITEM_QuestionText")) AND
                  TRIM(UPPER("GI"."Text"))=TRIM(UPPER("LLU"."GRADITEM_Text")) AND TRIM("TRX"."Procedure")=TRIM("LLU"."ProcedureCode"))
      35 - access("TRX"."Type"="GI"."Type" AND "TRX"."Id"="GI"."Id" AND "TRX"."Treatment"="GI"."Treatment")
      36 - access("TRX"."Procedure"="PROC"."Procedure")
      40 - access("PROC"."Discipline"="CLASS"."Class")
           filter("PROC"."Discipline"="CLASS"."Class")
      41 - filter("PROC"."Discipline" IS NOT NULL)
      42 - filter("TRX"."Grading"<>0 AND "TRX"."Deleted"=0 AND "TRX"."Status"='C')
      43 - filter("GI"."Grading"<>0)
      45 - access("TRX"."Producer"="P"."Producer")
      46 - filter("G"."Deleted"=0)
      47 - access("TRX"."Grading"="G"."Grading")
           filter("G"."Grading"<>0 AND "G"."Grading"="GI"."Grading")
      49 - access("TRX"."Producer"="U1"."Producer")
      51 - access("TRX"."Patient"="PAT"."Patient")
      61 - filter("GI"."IsHeading"=3 AND TRIM("GI"."QuestionText")='Comments' AND "GI"."Grading"<>0)
      62 - filter("TRX"."Grading"<>0 AND "TRX"."Deleted"=0 AND "TRX"."Status"='C' AND ("TRX"."Procedure"='G1002' OR
                  "TRX"."Procedure"='G1003'))
      63 - access("GI"."Type"="TRX"."Type" AND "GI"."Id"="TRX"."Id" AND "GI"."Treatment"="TRX"."Treatment")
      64 - filter("TRX"."Grading"<>0 AND "TRX"."Deleted"=0 AND "TRX"."Status"='C' AND ("TRX"."Procedure"='G1002' OR
                  "TRX"."Procedure"='G1003') AND "TRX"."Grading"="TRX"."Grading")
      65 - access("TRX"."Type"="TRX"."Type" AND "TRX"."Id"="TRX"."Id" AND "TRX"."Treatment"="TRX"."Treatment")
      66 - filter("GI"."RelValue"<>0 AND "TRX"."Type"="GI"."Type" AND "TRX"."Treatment"="GI"."Treatment")
      67 - access("TRX"."Id"="GI"."Id")
      68 - filter("G"."Deleted"=0)
      69 - access("TRX"."Grading"="G"."Grading")
           filter("G"."Grading"<>0 AND "GI"."Grading"="G"."Grading")
      71 - access("TRX"."Discipline"="CLASS"."Class")
      73 - access("TRX"."Producer"="P"."Producer")
      75 - access("TRX"."Patient"="PAT"."Patient")
      76 - access("TRX"."Producer"="U1"."Producer")
    138 rows selected.
    Elapsed: 00:00:00.62
    631015 rows selected.
    Elapsed: 00:01:49.13Output from AUTOTRACE (I think)
    NOTE: this post was too long for the forum, so I have removed a number of lines in the following output which appeared to be duplicating the above section (EXPLAIN PLAN).
    Statistics
           2657  recursive calls
              0  db block gets
       12734113  consistent gets
          13499  physical reads
              0  redo size
      103697740  bytes sent via SQL*Net to client
          69744  bytes received via SQL*Net from client
           6312  SQL*Net roundtrips to/from client
             76  sorts (memory)
              0  sorts (disk)
         631015  rows processedThe TKPROF output
    select * from llu_v_production_detail_03
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.51       0.51          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch     6312     88.09      98.01      13490   12733584          0      631015
    total     6314     88.60      98.52      13490   12733584          0      631015
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 57 
    Rows     Row Source Operation
    631015  VIEW  LLU_V_PRODUCTION_DETAIL_03 (cr=12733584 pr=13490 pw=0 time=92145592 us)
    631015   UNION-ALL  (cr=12733584 pr=13490 pw=0 time=91514573 us)
    125485    HASH JOIN  (cr=8099 pr=6396 pw=0 time=1523326 us)
       1725     VIEW  index$_join$_007 (cr=24 pr=0 pw=0 time=4777 us)
       1725      HASH JOIN  (cr=24 pr=0 pw=0 time=3051 us)
       1725       INDEX FAST FULL SCAN USERS_PRIMARY (cr=7 pr=0 pw=0 time=50 us)(object id 55023)
       1725       INDEX FAST FULL SCAN USERS_PRODUCER (cr=17 pr=0 pw=0 time=16 us)(object id 55024)
    144513     HASH JOIN  (cr=8075 pr=6396 pw=0 time=2326445 us)
       1396      TABLE ACCESS FULL PRODUCER (cr=107 pr=0 pw=0 time=29 us)
    144513      HASH JOIN  (cr=7968 pr=6396 pw=0 time=2035684 us)
         20       TABLE ACCESS FULL CLASS (cr=7 pr=0 pw=0 time=71 us)
    151043       TABLE ACCESS FULL QR_PRODUCTION (cr=7961 pr=6396 pw=0 time=313553 us)
    462685    FILTER  (cr=10755862 pr=7094 pw=0 time=58570941 us)
    466790     HASH JOIN  (cr=145247 pr=7094 pw=0 time=11007301 us)
       1725      VIEW  index$_join$_014 (cr=24 pr=0 pw=0 time=6817 us)
       1725       HASH JOIN  (cr=24 pr=0 pw=0 time=5091 us)
       1725        INDEX FAST FULL SCAN USERS_PRIMARY (cr=7 pr=0 pw=0 time=35 us)(object id 55023)
       1725        INDEX FAST FULL SCAN USERS_PRODUCER (cr=17 pr=0 pw=0 time=19 us)(object id 55024)
    485205      HASH JOIN  (cr=145223 pr=7094 pw=0 time=10945107 us)
         20       TABLE ACCESS FULL CLASS (cr=7 pr=0 pw=0 time=105 us)
    507772       HASH JOIN  (cr=145216 pr=7094 pw=0 time=11947534 us)
       1396        TABLE ACCESS FULL PRODUCER (cr=107 pr=0 pw=0 time=18 us)
    507772        HASH JOIN  (cr=145109 pr=7094 pw=0 time=10924473 us)
    188967         TABLE ACCESS FULL PATIENT (cr=31792 pr=0 pw=0 time=188998 us)
    507772         HASH JOIN  (cr=113317 pr=7094 pw=0 time=9652037 us)
        895          TABLE ACCESS FULL PROCEDUR (cr=46 pr=0 pw=0 time=65 us)
    509321          TABLE ACCESS FULL TRX (cr=113271 pr=7094 pw=0 time=5604567 us)
       8548     TABLE ACCESS FULL USERS (cr=10610615 pr=0 pw=0 time=39053120 us)
      42669    NESTED LOOPS  (cr=507317 pr=0 pw=0 time=3686506 us)
      42669     NESTED LOOPS  (cr=421535 pr=0 pw=0 time=3217140 us)
      45269      NESTED LOOPS  (cr=301155 pr=0 pw=0 time=2449542 us)
      45323       NESTED LOOPS  (cr=210131 pr=0 pw=0 time=2134056 us)
      45323        HASH JOIN  (cr=119056 pr=0 pw=0 time=1635472 us)
         95         TABLE ACCESS FULL LLU_EVALUATION_DESCRIPTIONS (cr=7 pr=0 pw=0 time=118 us)
      98272         HASH JOIN  (cr=119049 pr=0 pw=0 time=1446703 us)
      46996          HASH JOIN  (cr=109018 pr=0 pw=0 time=944857 us)
        786           MERGE JOIN  (cr=50 pr=0 pw=0 time=1528 us)
         20            TABLE ACCESS BY INDEX ROWID CLASS (cr=4 pr=0 pw=0 time=99 us)
         20             INDEX FULL SCAN CLASS_PRIMARY (cr=1 pr=0 pw=0 time=10 us)(object id 53850)
        786            SORT JOIN (cr=46 pr=0 pw=0 time=750 us)
        895             TABLE ACCESS FULL PROCEDUR (cr=46 pr=0 pw=0 time=18 us)
      47196           TABLE ACCESS FULL TRX (cr=108968 pr=0 pw=0 time=805137 us)
    696300          TABLE ACCESS FULL GRADITEM (cr=10031 pr=0 pw=0 time=277 us)
      45323        TABLE ACCESS BY INDEX ROWID PRODUCER (cr=91075 pr=0 pw=0 time=414937 us)
      45323         INDEX UNIQUE SCAN PRODUCER_PRIMARY (cr=45752 pr=0 pw=0 time=198709 us)(object id 54581)
      45269       TABLE ACCESS BY INDEX ROWID GRADING (cr=91024 pr=0 pw=0 time=353081 us)
      45270        INDEX UNIQUE SCAN GRADING_PRIMARY (cr=45753 pr=0 pw=0 time=173185 us)(object id 54088)
      42669      TABLE ACCESS BY INDEX ROWID USERS (cr=120380 pr=0 pw=0 time=703786 us)
      42669       INDEX RANGE SCAN USERS_PRODUCER (cr=46127 pr=0 pw=0 time=249186 us)(object id 55024)
      42669     TABLE ACCESS BY INDEX ROWID PATIENT (cr=85782 pr=0 pw=0 time=407452 us)
      42669      INDEX UNIQUE SCAN PATIENT_PRIMARY (cr=43098 pr=0 pw=0 time=198477 us)(object id 54370)
        176    TABLE ACCESS BY INDEX ROWID USERS (cr=49426 pr=0 pw=0 time=1783886 us)
        367     NESTED LOOPS  (cr=49149 pr=0 pw=0 time=6159428 us)
        190      NESTED LOOPS  (cr=48953 pr=0 pw=0 time=409391 us)
        190       NESTED LOOPS  (cr=48569 pr=0 pw=0 time=407105 us)
        190        NESTED LOOPS  (cr=48185 pr=0 pw=0 time=404820 us)
        191         NESTED LOOPS  (cr=47991 pr=0 pw=0 time=410291 us)
        193          NESTED LOOPS  (cr=47603 pr=0 pw=0 time=422507 us)
        193           NESTED LOOPS  (cr=46979 pr=0 pw=0 time=416890 us)
        193            NESTED LOOPS  (cr=46396 pr=0 pw=0 time=414374 us)
      14285             TABLE ACCESS FULL GRADITEM (cr=9602 pr=0 pw=0 time=85793 us)
        193             TABLE ACCESS BY INDEX ROWID TRX (cr=36794 pr=0 pw=0 time=128427 us)
       8218              INDEX UNIQUE SCAN TRX_PRIMARY (cr=28576 pr=0 pw=0 time=64353 us)(object id 54930)
        193            TABLE ACCESS BY INDEX ROWID TRX (cr=583 pr=0 pw=0 time=2169 us)
        193             INDEX UNIQUE SCAN TRX_PRIMARY (cr=390 pr=0 pw=0 time=918 us)(object id 54930)
        193           TABLE ACCESS BY INDEX ROWID GRADITEM (cr=624 pr=0 pw=0 time=4840 us)
       1547            INDEX RANGE SCAN GRADITEM_ID (cr=395 pr=0 pw=0 time=2910 us)(object id 54093)
        191          TABLE ACCESS BY INDEX ROWID GRADING (cr=388 pr=0 pw=0 time=1887 us)
        191           INDEX UNIQUE SCAN GRADING_PRIMARY (cr=197 pr=0 pw=0 time=943 us)(object id 54088)
        190         TABLE ACCESS BY INDEX ROWID CLASS (cr=194 pr=0 pw=0 time=1306 us)
        190          INDEX UNIQUE SCAN CLASS_PRIMARY (cr=4 pr=0 pw=0 time=551 us)(object id 53850)
        190        TABLE ACCESS BY INDEX ROWID PRODUCER (cr=384 pr=0 pw=0 time=1617 us)
        190         INDEX UNIQUE SCAN PRODUCER_PRIMARY (cr=194 pr=0 pw=0 time=715 us)(object id 54581)
        190       TABLE ACCESS BY INDEX ROWID PATIENT (cr=384 pr=0 pw=0 time=1941 us)
        190        INDEX UNIQUE SCAN PATIENT_PRIMARY (cr=194 pr=0 pw=0 time=939 us)(object id 54370)
        176      INDEX RANGE SCAN USERS_PRODUCER (cr=196 pr=0 pw=0 time=1389 us)(object id 55024)
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                    6312        0.00          0.00
      db file scattered read                       1614        0.02          2.08
      SQL*Net message from client                  6312        0.00         10.11
      SQL*Net more data to client                 48662        0.00          0.70
      db file sequential read                      4645        0.02          7.11
      latch: shared pool                              7        0.00          0.00
      latch: cache buffers chains                     1        0.00          0.00
    ********************************************************************************Again, I apologize if this is way more information than is necessary.
    All advice/suggestions/assistance will be gratefully accepted.
    Carl

    Hi Rob,
    Thank you for replying. Here is the view definition . . . it looks pretty convoluted, I know.
    I am reporting from a database which I have no control over other than to add indexes where needed.
    For reporting purposes, I am needing to create the dataset from a number of different tables; hence all the UNION clauses.
    -- CODE FOLLOWS
    CREATE OR REPLACE VIEW LLU_V_PRODUCTION_DETAIL_03
    AS
    SELECT
      'QR' AS "Source",
      U1."User" AS "UserID",
      QRP."ProviderID" AS "ProviderID",
      P."LastName" AS "ProviderLastName",
      P."FirstName" AS "ProviderFirstName",
      TO_CHAR(P."EndDate",'YYYY') AS "GraduationYear",
      P."PGroup",
      QRP."PatientID",
      QRP."ChartNumber",
      QRP."PatientLastName",
      QRP."PatientFirstName",
      QRP."ProcedureID" || '-' || QRP."ProcedureSuffix" AS "Procedure",
      QRP."ProcedureDescription",
      QRP."Tooth" AS "Site",
      QRP."Surface",
      QRP."axiUm_Discipline" AS "Discipline",
      "CLASS"."Rank" AS "DisciplineSorter",
      "CLASS"."Name" AS "DisciplineName",
      QRP."Points",
      0 AS "Hours",
      QRP."ServiceDate",
      0 AS "Id",
      QRP."UniqueID" AS "Grading",
      0 AS "LastSort",
      QRP."CategoryID",
      '' AS "CPAR comments"
    FROM QR_PRODUCTION QRP
    INNER JOIN PRODUCER P
      ON TRIM(QRP."ProviderID") = TRIM(P."Producer")
    INNER JOIN CLASS
      ON TRIM(QRP."axiUm_Discipline") = TRIM(CLASS."Class")
    INNER JOIN USERS U1
      ON QRP."ProviderID" = U1."Producer"
    WHERE (QRP."Location" < '9990')
    AND (QRP."ProviderID" IS NOT NULL)
    AND (QRP."ProcedureID" <> 185)
    -- skip the Cavender family - training patients
    AND NOT (QRP."PatientLastName" LIKE 'CAVENDER%' AND QRP."PatientFirstName" = 'TED')
    AND QRP."PatientFirstName" <> 'NON-PATIENT'
    --ORDER BY QRP."ProcedureID"
    UNION ALL
    SELECT
      'axiUm TRX' AS "Source",
      U1."User" AS "UserID",
      TRX."Producer" AS "ProviderID",
      P."LastName",
      P."FirstName",
      TO_CHAR(P."EndDate",'YYYY') AS "GraduationYear",
      P."PGroup",
      PAT."Patient",
      PAT."Chart",
      PAT."Last" AS "PatientLastName",
      PAT."First" AS "PatientFirstName",
      TRX."Procedure",
      PROC."Description",
      TRX."Site",
      TRX."Surface",
      TRIM(PROC."Discipline") AS "Discipline",
      "CLASS"."Rank" AS "DisciplineSorter",
      "CLASS"."Name",
      CASE WHEN
          ((TRX."Procedure" IN ('A0013','A0019','A0020','A0021','A0023','A0024','A0025','A0026','A0027','A0028','A0029','A0030','O179'))
          OR
          -- no points are to be awarded for any procedures performed on typodonts
          (EXISTS (SELECT 1 FROM PTTYPES PTT WHERE PTT."Patient" = PAT."Patient" and PTT."PatType" = 'TYPO' and PTT."Deleted" = 0)))
        AND  -- except for the following procedures
          (TRX."Procedure" NOT IN ('A0015','A0016','A0018','D0210'))
        THEN 0 ELSE PROC."RelValue" END AS "Points",
      CASE WHEN TRX."Procedure" IN ('A0013','A0019','A0020','A0021','A0023','A0024','A0025','A0026','A0027','A0028','A0029','A0030','O179')
        THEN PROC."RelValue" ELSE 0 END AS "Hours",
      TRX."TreatmentDate",
      TRX."Id",
      TRX."Grading",
      -1 AS "LastSort",
      -- additional link conditions added and table name changed on 1 July 2009 - cji
      SELECT "CategoryID" FROM LLU_CATEGORIES_X_PROCEDURES_03 LLU
      WHERE TRX."Procedure" = LLU."ProcedureID"
      AND TO_CHAR(P."EndDate",'YYYY') = LLU."GraduationYear"
      AND SUBSTR(TRX."Producer",1,1) = LLU."ProviderType"
      AND LLU."CategoryID" NOT IN (82)
      ) AS "CategoryID",
      '' AS "CPAR comments"
    FROM TRX
    INNER JOIN PATIENT PAT
      ON TRX."Patient" = PAT."Patient"
    INNER JOIN USERS U1
      ON TRX."Producer" = U1."Producer"
    INNER JOIN PROCEDUR PROC
      ON TRX."Procedure" = PROC."Procedure"
    INNER JOIN CLASS
      ON PROC."Discipline" = CLASS."Class"
    INNER JOIN PRODUCER P
      ON TRX."Producer" = P."Producer"
    WHERE (TRX."Status" = 'C')
    AND (TRX."Deleted" = 0)
    --AND (TRX."Grading" = 0)
    AND (TRX."Procedure" NOT LIKE 'D0149%')
    AND (TRX."Procedure" <> 'D5001C')
    -- exclude all procedures approved by Peds faculty ONLY FOR CLASS OF 2011 AND LATER
    -- EXCEPT FOR the Peds Block code (A0021 and A0022) - always include those
    AND NOT
    TRX."AppUser" IN (SELECT "User" FROM USERS WHERE "Custom3" = 'YES') -- Peds faculty
    AND
    TO_CHAR(P."EndDate",'YYYY') >= '2011'
    AND
    TRIM(TO_CHAR(P."EndDate",'YYYY')) IS NOT NULL
    AND
    TRX."Procedure" NOT IN ('A0021','A0022')
    UNION ALL
    SELECT
      'axiUm GRADING' AS "Source",
      U1."User" AS "UserID",
      TRX."Producer" AS "ProviderID",
      P."LastName",
      P."FirstName",
      TO_CHAR(P."EndDate",'YYYY'), -- Graduation year
      P."PGroup",
      PAT."Patient",
      PAT."Chart",
      PAT."Last" AS "PatientLastName",
      PAT."First" AS "PatientFirstName",
      TRX."Procedure",
      LLU."Description",
      TRX."Site",
      TRX."Surface",
      TRIM(PROC."Discipline") AS "Discipline",
      "CLASS"."Rank" AS "DisciplineSorter",
      "CLASS"."Name",
      LLU."Points", --LLU_POINTS_FROM_EVALUATIONS(TRX."Procedure", nvl(GI."Text",0)),
      0 AS "Hours",
      TRX."TreatmentDate",
      GI."Id",
      GI."Grading",
      GI."Row" AS "LastSort",
      LLU."CategoryID",
      '' AS "CPAR comments"
    FROM TRX
    INNER JOIN PATIENT PAT
      ON TRX."Patient" = PAT."Patient"
    INNER JOIN PRODUCER P
      ON TRX."Producer" = P."Producer"
    INNER JOIN GRADING G
      ON TRX."Grading" = G."Grading"
    INNER JOIN GRADITEM GI
      ON G."Grading" = GI."Grading"
      AND TRX."Type" = GI."Type"
      AND TRX."Id" = GI."Id"
      AND TRX."Treatment" = GI."Treatment"
    INNER JOIN PROCEDUR PROC
      ON TRX."Procedure" = PROC."Procedure"
    INNER JOIN CLASS
      ON PROC."Discipline" = CLASS."Class"
    INNER JOIN LLU_EVALUATION_DESCRIPTIONS LLU
      ON (TRIM(UPPER(GI."QuestionText")) = TRIM(UPPER(LLU."GRADITEM_QuestionText")))
      AND (TRIM(UPPER(GI."Text")) = TRIM(UPPER(LLU."GRADITEM_Text")))
      AND (TRIM(TRX."Procedure") = TRIM(LLU."ProcedureCode"))
    INNER JOIN USERS U1
      ON TRX."Producer" = U1."Producer"
    WHERE (TRX."Status" = 'C')
    AND (TRX."Deleted" = 0)
    AND (TRX."Grading" <> 0)
    AND (G."Deleted" = 0)
    UNION ALL
    SELECT 'ClinPtsAdj',
      U1."User" AS "UserID",
      TRX."Producer",
      P."LastName", P."FirstName",
      TO_CHAR(P."EndDate",'YYYY'), -- Graduation year
      P."PGroup", PAT."Patient", PAT."Chart", PAT."Last", PAT."First",
      TRX."Procedure",
      'Clinic points adjustment',
      '' AS "Site",
      '' AS "Surface",
      TRIM(TRX."Discipline"),
      "CLASS"."Rank",
      "CLASS"."Name",
      DERIVED."Points",
      0 AS "Hours",
      GI."Date",
      GI."Id",
      GI."Grading",
      GI."Row",
      NULL AS "CategoryID",
      TRIM(REPLACE(GI."Note", CHR(13) || CHR(10), ' '))
    FROM TRX
    INNER JOIN PATIENT PAT
      ON (TRX."Patient" = PAT."Patient")
    INNER JOIN PRODUCER P
      ON (TRX."Producer" = P."Producer")
    INNER JOIN CLASS
      ON (TRX."Discipline" = CLASS."Class")
    INNER JOIN GRADING G
      ON (TRX."Grading" = G."Grading")
    INNER JOIN GRADITEM GI
      ON (GI."Grading" = G."Grading")
      AND (GI."Type" = TRX."Type")
      AND (GI."Id" = TRX."Id")
      AND (GI."Treatment" = TRX."Treatment")
    INNER JOIN USERS U1
      ON TRX."Producer" = U1."Producer"
    INNER JOIN
      SELECT TRX."Type", TRX."Id", TRX."Treatment", TRX."Grading",
        CASE WHEN TRX."Procedure" = 'G1003' THEN GI."RelValue" * -1 ELSE "RelValue" END AS "Points"
      FROM TRX, GRADITEM GI
      WHERE (TRX."Type" = GI."Type")
      AND (TRX."Id" = GI."Id")
      AND (TRX."Treatment" = GI."Treatment")
      AND (TRX."Procedure" IN ('G1002','G1003'))
      AND (TRX."Status" = 'C')
      AND (TRX."Deleted" = 0)
      AND (TRX."Grading" <> 0)
      AND (GI."RelValue" <> 0)
      ) DERIVED
      ON (TRX."Type" = DERIVED."Type")
      AND (TRX."Id" = DERIVED."Id")
      AND (TRX."Treatment" = DERIVED."Treatment")
      AND (TRX."Grading" = DERIVED."Grading")
    WHERE (TRX."Status" = 'C')
    AND (TRX."Deleted" = 0)
    AND (TRX."Grading" <> 0)
    AND (G."Deleted" = 0)
    AND (TRX."Procedure" IN ('G1002','G1003'))
    AND (GI."IsHeading" = 3)
    AND (TRIM(GI."QuestionText") = 'Comments')
    --ORDER BY "ProviderID", "DisciplineSorter", "Id", "Grading", "Site", "LastSort";A couple of additional points:
    The table USERS already had an index on column "Producer"; I added an index on column "Custom3" but it did not seem to make any difference.
    Table USERS has 1,725 rows
    Table PRODUCER (aliased as P) has 1,396 rows
    Table TRX has 1,443,764 rows.
    Any additional information you need I will be glad to provide.
    Thanks a bunch; it may not be too late to teach an old dog new tricks.
    And thank you all for the kind words about the posting; about the only thing I can do well is follow directions.
    Carl

  • Please reply for the query tuning

    Hi, i am a beginner in oracle dba, I have to know if i have studied little bit about query tuning in ORACLE.
    I wanna know if i have the following query and its plan then how it can be tuned:
    QUERY:
              SELECT z.emplid ,h.first_name || ' ' || h.last_name  ,z.grade ,z.DEPTID ,z.LOCATION
                              FROM sysadm.ps_lnt_latestbu_vw z, sysadm.ps_personal_data h
                                    WHERE  z.empl_status ='A'    --index access
                                    AND z.emplid = h.emplid      --join
                                    and z.emplid not in   (select g.emplid from sysadm.ps_lnt_asn_skl_tbl g)    --join
                                    and z.Business_unit=
                                                               (      select l.lnt_subunit from sysadm.ps_position_data l where l.position_nbr in
                                                                                                    ( select b.position_nbr from sysadm.ps_job b,sysadm.psoprdefn y
                                                                                                              where b.effdt=(     select max(g.effdt) from sysadm.ps_job g
                                                                                                                                            where g.emplid=b.emplid           --join costs high
                                                                                                                                                and g.effdt<=SYSDATE)               --filter/index
                                                                                                                    and b.effseq=
                                                                                                                             (select max(h.effseq) from sysadm.ps_job h
                                                                                                                                       where h.emplid=b.emplid           --join costs high
                                                                                                                                      and h.effdt=b.effdt)               --join costs high
                                                                                                                and b.empl_rcd=0          --filter/index access
                                                                                                                and y.EMPLID=b.EMPLID  --join
                                                                                                                and y.OPRID='1112'   -- filter/index access
                                               order by z.emplid
                                            /AND its plan is:
    Execution Plan
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=1 Bytes=64)
       1    0   SORT (ORDER BY) (Cost=6 Card=1 Bytes=64)
       2    1     NESTED LOOPS (ANTI) (Cost=4 Card=1 Bytes=64)
       3    2       NESTED LOOPS (Cost=3 Card=1 Bytes=56)
       4    3         VIEW OF 'PS_LNT_LATESTBU_VW' (Cost=2 Card=1 Bytes=31)
       5    4           UNION-ALL
       6    5             CONCATENATION
       7    6               TABLE ACCESS (BY INDEX ROWID) OF 'PS_POSITION_DATA' (Cost=5 Card=90 Bytes=1890)
       8    7                 NESTED LOOPS
       9    8                   NESTED LOOPS (Cost=275 Card=1 Bytes=90)
      10    9                     NESTED LOOPS (Cost=275 Card=1 Bytes=82)
      11   10                       TABLE ACCESS (BY INDEX ROWID) OF 'PS_JOB' (Cost=3 Card=1 Bytes=50)
      12   11                         INDEX (RANGE SCAN) OF 'PS2JOB' (NON-UNIQUE) (Cost=2 Card=1)
      13   12                           SORT (AGGREGATE)
      14   13                             FIRST ROW (Cost=3 Card=1 Bytes=19)
      15   14                               INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      16   12                           SORT (AGGREGATE)
      17   16                             FIRST ROW (Cost=3 Card=1 Bytes=22)
      18   17                               INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      19   10                       INDEX (UNIQUE SCAN) OF 'PS_EMPLOYMENT'(UNIQUE)
      20    9                     INDEX (UNIQUE SCAN) OF 'PS_PERSONAL_DATA' (UNIQUE)
      21    8                   INDEX (RANGE SCAN) OF 'PS_POSITION_DATA' (UNIQUE) (Cost=5 Card=90)
      22    6               FILTER
      23   22                 NESTED LOOPS (Cost=275 Card=1 Bytes=90)
      24   23                   NESTED LOOPS (Cost=275 Card=1 Bytes=82)
      25   24                     NESTED LOOPS (Cost=275 Card=1 Bytes=71)
      26   25                       INDEX (FAST FULL SCAN) OF 'PS8POSITION_DATA' (NON-UNIQUE) (Cost=5 Card=90 Bytes=1890)
      27   25                       TABLE ACCESS (BY INDEX ROWID) OF 'PS_JOB' (Cost=3 Card=1 Bytes=50)
      28   27                         INDEX (RANGE SCAN) OF 'PS2JOB' (NON-UNIQUE) (Cost=2 Card=1)
      29   28                           SORT (AGGREGATE)
      30   29                             FIRST ROW (Cost=3 Card=1 Bytes=22)
      31   30                               INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      32   28                           SORT (AGGREGATE)
      33   32                             FIRST ROW (Cost=3 Card=1 Bytes=19)
      34   33                               INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      35   24                     INDEX (UNIQUE SCAN) OF 'PS_EMPLOYMENT' (UNIQUE)
      36   23                   INDEX (UNIQUE SCAN) OF 'PS_PERSONAL_DATA'(UNIQUE)
      37   22                 SORT (AGGREGATE)
      38   37                   FIRST ROW (Cost=2 Card=1 Bytes=17)
      39   38                     INDEX (RANGE SCAN (MIN/MAX)) OF 'PS_POSITION_DATA' (UNIQUE) (Cost=2 Card=9000)
      40    5             FILTER
      41   40               NESTED LOOPS (Cost=751 Card=1 Bytes=191)
      42   41                 NESTED LOOPS (OUTER) (Cost=750 Card=1 Bytes=167)
      43   42                   NESTED LOOPS (OUTER) (Cost=749 Card=1 Bytes=143)
      44   43                     NESTED LOOPS (Cost=748 Card=1 Bytes=134)
      45   44                       NESTED LOOPS (Cost=748 Card=1 Bytes=123)
      46   45                         NESTED LOOPS (Cost=748 Card=1 Bytes=119)
      47   46                           NESTED LOOPS (Cost=747 Card=1 Bytes=98)
      48   47                             NESTED LOOPS (Cost=744 Card=1 Bytes=62)
      49   48                               NESTED LOOPS (Cost=744 Card=1Bytes=54)
      50   49                                 VIEW OF 'PS_LNTPRJOBSYSJRVW'(Cost=741 Card=1 Bytes=9)
      51   50                                   FILTER
      52   51                                     NESTED LOOPS (OUTER) (Cost=735 Card=1 Bytes=68)
      53   52                                       NESTED LOOPS (Cost=734Card=1 Bytes=51)
      54   53                                         NESTED LOOPS (Cost=734 Card=1 Bytes=43)
      55   54                                           TABLE ACCESS (BY INDEX ROWID) OF 'PS_JOB' (Cost=734 Card=1 Bytes=32)
      56   55                                             INDEX (RANGE SCAN) OF 'PSCJOB' (NON-UNIQUE) (Cost=206 Card=1013)
      57   54                                           INDEX (UNIQUE SCAN) OF 'PS_EMPLOYMENT' (UNIQUE)
      58   53                                         INDEX (UNIQUE SCAN) OF 'PS_PERSONAL_DATA' (UNIQUE)
      59   52                                       INDEX (RANGE SCAN) OF'PS_POSITION_DATA' (UNIQUE) (Cost=1 Card=1 Bytes=17)
      60   51                                     SORT (AGGREGATE)
      61   60                                       FIRST ROW (Cost=3 Card=1 Bytes=19)
      62   61                                         INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      63   51                                     SORT (AGGREGATE)
      64   63                                       FIRST ROW (Cost=3 Card=1 Bytes=22)
      65   64                                         INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      66   51                                     SORT (AGGREGATE)
      67   66                                       FIRST ROW (Cost=2 Card=1 Bytes=17)
      68   67                                         INDEX (RANGE SCAN (MIN/MAX)) OF 'PS_POSITION_DATA' (UNIQUE) (Cost=2 Card=9000)
      69   49                                 TABLE ACCESS (BY INDEX ROWID) OF 'PS_JOB' (Cost=3 Card=1 Bytes=45)
      70   69                                   INDEX (RANGE SCAN) OF 'PSAJOB' (NON-UNIQUE) (Cost=2 Card=1)
      71   70                                     SORT (AGGREGATE)
      72   71                                       INDEX (RANGE SCAN) OF'PSAJOB' (NON-UNIQUE) (Cost=3 Card=1 Bytes=19)
      73   72                                         SORT (AGGREGATE)
      74   73                                           FIRST ROW (Cost=3Card=8 Bytes=88)
      75   74                                             INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=25963)
      76   70                                     SORT (AGGREGATE)
      77   76                                       FIRST ROW (Cost=3 Card=8 Bytes=88)
      78   77                                         INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=25963)
      79   48                               INDEX (UNIQUE SCAN) OF 'PS_PERSONAL_DATA' (UNIQUE)
      80   47                             TABLE ACCESS (BY INDEX ROWID) OF'PS_JOB' (Cost=3 Card=1 Bytes=36)
      81   80                               INDEX (RANGE SCAN) OF 'PSAJOB'(NON-UNIQUE) (Cost=2 Card=1)
      82   81                                 SORT (AGGREGATE)
      83   82                                   FIRST ROW (Cost=3 Card=1 Bytes=19)
      84   83                                     INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      85   81                                 SORT (AGGREGATE)
      86   85                                   FIRST ROW (Cost=3 Card=1 Bytes=22)
      87   86                                     INDEX (RANGE SCAN (MIN/MAX)) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=207700)
      88   46                           INDEX (RANGE SCAN) OF 'PS8POSITION_DATA' (NON-UNIQUE) (Cost=1 Card=1 Bytes=21)
      89   45                         INDEX (UNIQUE SCAN) OF 'PS_BUS_UNIT_TBL_HR' (UNIQUE)
      90   44                       INDEX (UNIQUE SCAN) OF 'PS_EMPLOYMENT'(UNIQUE)
      91   43                     INDEX (RANGE SCAN) OF 'PS_POSITION_DATA'(UNIQUE) (Cost=1 Card=1 Bytes=9)
      92   42                   INDEX (FULL SCAN) OF 'PS0LOCATION_TBL' (NON-UNIQUE) (Cost=1 Card=1 Bytes=24)
      93   41                 INDEX (RANGE SCAN) OF 'PS0LOCATION_TBL' (NON-UNIQUE) (Cost=1 Card=1 Bytes=24)
      94   40               SORT (AGGREGATE)
      95   94                 FIRST ROW (Cost=2 Card=1 Bytes=17)
      96   95                   INDEX (RANGE SCAN (MIN/MAX)) OF 'PS_POSITION_DATA' (UNIQUE) (Cost=2 Card=9000)
      97    4           TABLE ACCESS (BY INDEX ROWID) OF 'PS_POSITION_DATA' (Cost=2 Card=1 Bytes=13)
      98   97             NESTED LOOPS (Cost=9 Card=1 Bytes=19)
      99   98               VIEW OF 'VW_NSO_1' (Cost=5 Card=1 Bytes=6)
    100   99                 SORT (UNIQUE)
    101  100                   NESTED LOOPS (Cost=5 Card=1 Bytes=44)
    102  101                     TABLE ACCESS (BY INDEX ROWID) OF 'PSOPRDEFN' (Cost=2 Card=1 Bytes=14)
    103  102                       INDEX (UNIQUE SCAN) OF 'PS_PSOPRDEFN'(UNIQUE) (Cost=1 Card=1)
    104  101                     TABLE ACCESS (BY INDEX ROWID) OF 'PS_JOB' (Cost=3 Card=1 Bytes=30)
    105  104                       INDEX (RANGE SCAN) OF 'PSAJOB' (NON-UNIQUE) (Cost=2 Card=1)
    106  105                         SORT (AGGREGATE)
    107  106                           INDEX (RANGE SCAN) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=8 Bytes=128)
    108  105                         SORT (AGGREGATE)
    109  108                           INDEX (RANGE SCAN) OF 'PSAJOB' (NON-UNIQUE) (Cost=3 Card=1 Bytes=19)
    110   98               INDEX (RANGE SCAN) OF 'PS_POSITION_DATA' (UNIQUE) (Cost=1 Card=1)
    111    3         TABLE ACCESS (BY INDEX ROWID) OF 'PS_PERSONAL_DATA'(Cost=1 Card=1 Bytes=25)
    112  111           INDEX (UNIQUE SCAN) OF 'PS_PERSONAL_DATA' (UNIQUE)
    113    2       INDEX (RANGE SCAN) OF 'PS_LNT_ASN_SKL_TBL' (UNIQUE) (Cost=1 Card=10076 Bytes=80608)
    Statistics
             70  recursive calls
              0  db block gets
        1186931  consistent gets
           5660  physical reads
             60  redo size
            462  bytes sent via SQL*Net to client
            373  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              2  sorts (memory)
              0  sorts (disk)
              0  rows processedMy thoughts for this is:
    1. NLJ high cost -- rewrite inner sub-query
    2. sort is done for each join for max function every time so,     therefore try use use sort merge hint
    3. h           alias has been referenced twice for table name.
    PLEASE TELL ME WHAT TO DO IF I AM ORACLE DBA.
    Thanks in advance.
    Edited by: user2060331 on Mar 25, 2010 9:17 AM
    Edited by: user2060331 on Mar 25, 2010 9:21 AM
    Edited by: user2060331 on Mar 25, 2010 9:32 AM
    Edited by: user2060331 on Mar 25, 2010 9:47 AM

    No it's not. You should see indentations for each level of the explain plan. You've lost all of it. It should look like this (not your query):
    PLAN_TABLE_OUTPUT
    | Id  | Operation                   | Name                | Rows  | Bytes | Cost  | Inst   |IN-OUT|
    |   0 | SELECT STATEMENT            |                     | 16116 |  2911K|   712 |        |      |
    |   1 |  FILTER                     |                     |       |       |       |        |      |
    |   2 |   CONNECT BY WITH FILTERING |                     |       |       |       |        |      |
    |   3 |    FILTER                   |                     |       |       |       |        |      |
    |   4 |     COUNT                   |                     |       |       |       |        |      |
    |   5 |      HASH JOIN RIGHT OUTER  |                     | 16116 |  2911K|   712 |        |      |
    |   6 |       REMOTE                | LSW_USR_GRP_XREF    |   518 | 13986 |     4 | MYPROJ~ | R->S |
    |   7 |       HASH JOIN RIGHT OUTER |                     | 16116 |  2486K|   707 |        |      |
    |   8 |        REMOTE               | LSW_USR_XREF        |   222 |  2886 |     4 | MYPROJ~ | R->S |
    |   9 |        HASH JOIN RIGHT OUTER|                     | 16116 |  2282K|   702 |        |      |
    |  10 |         TABLE ACCESS FULL   | MYPROJ_PROCESS_MAP   |   176 |  4752 |     4 |        |      |
    |  11 |         HASH JOIN OUTER     |                     | 16116 |  1857K|   698 |        |      |
    |  12 |          TABLE ACCESS FULL  | MYPROJ_MPPA | 16116 |  1243K|    71 |        |      |
    |  13 |          REMOTE             | LSW_TASK            | 80730 |  3074K|   625 | MYPROJ~ | R->S |
    |  14 |    HASH JOIN                |                     |       |       |       |        |      |
    |  15 |     CONNECT BY PUMP         |                     |       |       |       |        |      |
    |  16 |     COUNT                   |                     |       |       |       |        |      |
    |  17 |      HASH JOIN RIGHT OUTER  |                     | 16116 |  2911K|   712 |        |      |
    |  18 |       REMOTE                | LSW_USR_GRP_XREF    |   518 | 13986 |     4 | MYPROJ~ | R->S |
    |  19 |       HASH JOIN RIGHT OUTER |                     | 16116 |  2486K|   707 |        |      |
    |  20 |        REMOTE               | LSW_USR_XREF        |   222 |  2886 |     4 | MYPROJ~ | R->S |
    |  21 |        HASH JOIN RIGHT OUTER|                     | 16116 |  2282K|   702 |        |      |
    |  22 |         TABLE ACCESS FULL   | MYPROJ_PROCESS_MAP   |   176 |  4752 |     4 |        |      |
    |  23 |         HASH JOIN OUTER     |                     | 16116 |  1857K|   698 |        |      |
    |  24 |          TABLE ACCESS FULL  | MYPROJ_MPPA | 16116 |  1243K|    71 |        |      |
    |  25 |          REMOTE             | LSW_TASK            | 80730 |  3074K|   625 | MYPROJ~ | R->S |
    ---------------------------------------------------------------------------------------------------

  • Query tuning : you can do it yourself

    Hello,
    This thread is not a question.
    How tune my query ?
    My query didn't use indexes why ?
    I have indexes on table, stats are up-to-date why Oracle does a full scan on table ?
    What are the hint which I can use ?
    etc...
    I would like try to answer to many such questions posted in this forum about query tuning.
    And explain that tuning is not always complicated, is not always reserved to some consultants, is not always solved by hints usage, and not require to buy some books which would give some magic solutions.
    By this thread, I would explain to people which have some query performance issues, that the solution is maybe here, in front of their eyes, inside the query itself. The solution may come from their own side, and that they can be happy to solve such question themself.
    I'll develop here below a case from a real word situation encountered some time ago.

    At this point, remove this huge and nightmarish hint. We'll use it only if no other ways may found.
    First, a look into the data model to see if the joins may be rewrite differently.
    Original joins :
        dw.AIRPORT_ROUTING_ID = ar.AIRPORT_ROUTING_ID and
        dw.COUNTRY_ROUTING_ID = cor.COUNTRY_ROUTING_ID and
        dw.REGION_ROUTING_ID = rr.REGION_ROUTING_ID and
        dw.CITY_ROUTING_ID  = cr.CITY_ROUTING_ID andAnd indeed, the join may be rewrite as below :
        and dw.AIRPORT_ROUTING_ID = ar.AIRPORT_ROUTING_ID
        and ar.CITY_ROUTING_ID    = cr.CITY_ROUTING_ID
        and cr.COUNTRY_ROUTING_ID = cor.COUNTRY_ROUTING_ID 
        and cor.REGION_ROUTING_ID = rr.REGION_ROUTING_IDNote the aliases were change here. Is it complicated to try to rewrite query like that ?
    Secondly, we will try to see how avoid or, at least, workaround the all OR conditions. It would be well if we could merge all the FROM (bind variable :a) in one column, same for all TO (bind variable :b), unfortunately, the data model cannot be change (of course). Ok, we will try to work with a temporary table by combining all the possiblities between the two conditions.
    create global temporary table REGION_ROUTING_TMP
    on commit preserve rows
    as
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_FROM as REGION_FROM, REGION_STOP1 as REGION_TO
    from   REGION_ROUTING
    where  1=2;And an index based on the two mains criteria of the query may help :
    create index IDX_REGION_ROUTING_TMP on REGION_ROUTING_TMP(REGION_FROM,REGION_TO);Then we'll populate table :
    insert into REGION_ROUTING_TMP
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_FROM as REGION_FROM, REGION_STOP1 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_FROM as REGION_FROM, REGION_STOP2 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_FROM as REGION_FROM, REGION_STOP3 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_FROM as REGION_FROM, REGION_TO as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP1 as REGION_FROM, REGION_STOP2 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP1 as REGION_FROM, REGION_STOP3 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP1 as REGION_FROM, REGION_TO as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP2 as REGION_FROM, REGION_STOP3 as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP2 as REGION_FROM, REGION_TO as REGION_TO
    from   REGION_ROUTING
    union
    select REGION_ROUTING_NAMES, REGION_ROUTING_ID, REGION_STOP3 as REGION_FROM, REGION_TO as REGION_TO
    from   REGION_ROUTING;The insert take near 9 seconds, which is a reasonnable elapse time.
    At this point, the query become :
    Select
       ap.AIRPORT_PAIR,  
       dw.DELIVERY_PERIOD,
       dw.TOTAL_PAX As Demand,
       od.GLOBAL_TOTAL_PAX as Total_OD_Demand,
       dw.REPORTED_PAX As ReportedPax,
       ap.AIRPORT_FROM,
       ap.AIRPORT_TO,
       ap.CITY_FROM,
       ap.CITY_TO,
       ap.COUNTRY_FROM_NAME,
       ap.COUNTRY_TO_NAME,
       ap.REGION_FROM_NAME,
       ap.REGION_TO_NAME,
       ar.AIRPORT_ROUTING,
       cr.CITY_ROUTING,
       cor.COUNTRY_ROUTING_NAMES,
       rr.REGION_ROUTING_NAMES,
       ar.NUMBER_OF_STOP,
       dw.PERCENT_OF_TOTAL_PAX_VS_OD,
       dw.AIRLINE1,
       dw.AIRLINE2,
       dw.AIRLINE3,
       dw.AIRLINE4,
       dw.NUMBER_OF_AIRLINE,
       dw.AIRCRAFTCLASS_NAME,
       dw.FARE
    From
       REGION_ROUTING_TMP rr, -- here we use now the temporary table instead of REGION_ROUTING table
       DETAILED_FLIGHTS dw,
       AIRPORT_PAIR ap,
       AIRPORT_ROUTING ar,
       CITY_ROUTING cr,
       COUNTRY_ROUTING cor,
       OD od
    where
            dw.DELIVERY_PERIOD  in ('2006-09','2006-08','2006-07')
    and dw.AIRPORT_PAIR_ID    = ap.AIRPORT_PAIR_ID
    and dw.OD_ID              = od.OD_ID
    and dw.AIRPORT_ROUTING_ID = ar.AIRPORT_ROUTING_ID
    and ar.CITY_ROUTING_ID    = cr.CITY_ROUTING_ID
    and     cr.COUNTRY_ROUTING_ID = cor.COUNTRY_ROUTING_ID 
    and cor.REGION_ROUTING_ID = rr.REGION_ROUTING_ID
    and rr.REGION_FROM        = '7'  |
    and rr.REGION_TO          = '8'  |-> these two lines replace all the OR conditions;And explain plan :
    | Id  | Operation                             |  Name                          | Rows  | Bytes | Cost  | Pstart| Pstop |
    |   0 | SELECT STATEMENT                      |                                |   469 |   174K|  3462 |       |       |
    |   1 |  NESTED LOOPS                         |                                |   469 |   174K|  3462 |       |       |
    |   2 |   NESTED LOOPS                        |                                |   458 |   166K|  3004 |       |       |
    |   3 |    NESTED LOOPS                       |                                |   454 |   127K|  2096 |       |       |
    |   4 |     NESTED LOOPS                      |                                |   258 | 58308 |   548 |       |       |
    |   5 |      NESTED LOOPS                     |                                |   246 | 48216 |    56 |       |       |
    |   6 |       NESTED LOOPS                    |                                |    26 |  4420 |     4 |       |       |
    |   7 |        TABLE ACCESS BY INDEX ROWID    | REGION_ROUTING_TMP             |     1 |   123 |   
    |*  8 |         INDEX RANGE SCAN              | IDX_REGION_ROUTING_TMP         |     1 |       |     1 |       | 
    |   9 |        TABLE ACCESS BY INDEX ROWID    | COUNTRY_ROUTING                |    32 |  1504 |     2
    |* 10 |         INDEX RANGE SCAN              | IX9_COUNTRY_ROUTING            |    32 |       |     1 |       | 
    |  11 |       TABLE ACCESS BY INDEX ROWID     | CITY_ROUTING                   |     9 |   234 |     2 | 
    |* 12 |        INDEX RANGE SCAN               | IX9_CITY_ROUTING               |    12 |       |     1 |    
    |  13 |      TABLE ACCESS BY INDEX ROWID      | AIRPORT_ROUTING                |     1 |    30 |     2
    |* 14 |       INDEX RANGE SCAN                | IX10_AIRPORT_ROUTING           |     1 |       |     1 |   
    |* 15 |     TABLE ACCESS BY GLOBAL INDEX ROWID| DETAILED_FLIGHTS               |     2 |   122 |   
    |* 16 |      INDEX RANGE SCAN                 | IX3_DETAILED_FLIGHTS           |     9 |       |     2 |    
    |  17 |    TABLE ACCESS BY INDEX ROWID        | AIRPORT_PAIR                   |     1 |    85 |     2 |  
    |* 18 |     INDEX RANGE SCAN                  | IX1_AIRPORT_PAIR               |     1 |       |     1 |       |
    |  19 |   TABLE ACCESS BY INDEX ROWID         | OD                             |     1 |    10 |     1 |       |   
    |* 20 |    INDEX UNIQUE SCAN                  | PK_OD                          |     1 |       |       |       |       |
    ----------------------------------------------------------------------------------------------------Ouf, this sound like better, isn't it ? Was it complicated to arrive as such result ?
    Ok, now launch the query and see the elapse time :
    104103 rows selected.
    Elapsed: 00:09:00.12
    Statistics
              0  recursive calls
              0  db block gets
        1214845  consistent gets
         272481  physical reads
              0  redo size
       11164355  bytes sent via SQL*Net to client
         257032  bytes received via SQL*Net from client
           6942  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         104103  rows processedWoaw, developer is now very happy, less than 10 minutes instead of one hour... and without modify anything else in database and server settings, without add indexes, without add any hints...
    Ok, now the problem is in the number of returned lines. Have you see the number of return client/server ? We'll now to try to reduce this one. Increasing the number of line returned by fetch :
    set arraysize 5000
    --run the query
    104103 rows selected.
    Elapsed: 00:02:25.49
    Statistics
              0  recursive calls
              0  db block gets
        1150893  consistent gets
         271432  physical reads
              0  redo size
       11018641  bytes sent via SQL*Net to client
           1013  bytes received via SQL*Net from client
             22  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
         104103  rows processedOk, the number of retunr client/server is now low, and elapse time is ok user.

  • Query tuning basics..

    Friends and gurus...
    OS: Linux
    DB: 11gR2
    Recently I have found myself trapped into many sql query tuning with and without bind variables and main aim of all tuning is to reduce total elapsed time displayed in AWR report.
    I found myself run all over the places just to identify problem and then try to solve it..
    with near to zero experience in query tuning I'm trying to learn this art and have below questions...
    Q.
    1. Identify problem: could somebody please list what all internal oracle tools available just to identify problem and what should be best approach?
    like sqltrace, explain plan, tkprof etc... list goes on so wanting to know which to follow and when...
    2. any idea how to get all details of steps listed in explain plan? since predicate information only list few steps where filter is used but some steps which takes long (hash join, nested loops) I don't know what caused it...
    3. how to identify problems in queries with bind variable?
    please note I don't have any 3rd party tool and all I work on is sqlplus session.
    thanks,

    khallas301, beside SB's reference to the Performance and Tuning Guide I want to point out that use of the AWR requires purchase of the extra cost EM Diagnositc and potentially also the Performance Pack License.
    You can use statspack if you do not have the EM liceses.
    How you approach what to tune depends a bit on the envornment. If only a few processes are having issues then you can look into customer complaints and tune what people are complaigning about. On the other hand if the entire system is having issues then you might want to identify critical processes and start with them.
    One approach would be to run sql trace on a critical process. Review the traces and tune the SQL statements you find having issues. Record the results and move on to the next critical process.
    Another approach would be to query the dynamic performance views for SQL with high logical IO counts, determine what processes the SQL is coming from, and tune that SQL.
    HTH -- Mark D Powell --

  • Query tuning and using the "better" index.

    I have a database table with about 40,000 records in it. Using
    a certain index first limits the number of rows to 11,000
    records. Using a different index first (by disabling the other
    index in the query) limits the number of rows to 2,500 records.
    Using the explain plan, the rest of the query is parsed the same
    way for both queries. What reasons can explain why when the
    index that returns 11,000 records first runs faster than
    the "better" index? I thought the whole idea behind query
    tuning is to use the index that limits the data the most.

    It looks like Oracle likes the equality condition more than the greater than -less than combination (which you might like to recode as a BETWEEN condition for clarity).
    There are a number of factors here.
    i) Are the "test names" equally distributed? Do some test names appear with greater frequency than others? If so, collecting column statistics might cause the BATCH_2 index to be used for some test names, and not for others.
    ii) Likewise, what is the distribution of cdates? How does the distribution of cdates vary by test name?
    iii) You could force the use of the BATCH_6 index over the BATCH_2 by using an optimizer hint instead of dropping the BATCH_2 index ...
    select /*+ index(batch batch_6) */ id, test, cdate
    from batch
    where test = 'Some test name'
    and cdate >= &start date&
    and cdate < &end date& + 1
    ... or even try prompting Oracle to use both indexes ...
    select /*+ index(batch batch_6) index(batch batch_2) */ id, test, cdate
    from batch
    where test = 'Some test name'
    and cdate >= &start date&
    and cdate < &end date& + 1
    ... and test the response times, then chose to use the optimizer hint in your application
    iv) You might like to replace the rather unselective BATCH_2 index with a BATCH_2_6 index on both test and cdate (in that order). That would probably give you an excellent result, and the BATCH_6 index can still be used to satisfy queries slective on cdate that are not selective on test (in very recent versions of Oracle the BATCH_2_6 index might be used for such an operation, and you could drop both BATCH_6 and BATCH_2)
    Well, see if any of this helps.

  • Sql query tuning

    How can i do SQl QUERY TUNING in Oracle 9i Database

    Hello,
    How can i do SQl QUERY TUNING in Oracle 9i Database You can start through reviewing the Performance Tuning Guide;
    http://download.oracle.com/docs/cd/B10501_01/server.920/a96533/toc.htm
    Good Luck!
    Adith

  • Calculating the memory and performance of a oracle query

    Hi,
    I am now developing application in java with oracle as a back-end. In my application i require lot of queries to be executed. Hence, the system is getting is slow due to queries.
    So, i planned to develop one Stand-alone application in java, that should show the statistics like, memory and performance. for ex:- if i enter one SQL query in the text box, my standalone application should display, the processing time it requires to fetch the values and the memory is used for that query.
    Can anybody give ideas, suggestion, etc etc...
    Thanks in Advance
    Regards,
    Rajkumar

    This is now Oracle question, not JDBC question. :)
    Followings are sample for explain plan/autotrace/SQL*Trace.
    (You really need to read stuffs like Oracle SQL Tuning books...)
    SQL> create table a as select object_id, object_name from all_objects
    2 where rownum <= 100;
    Table created.
    SQL> create index a_idx on a(object_id);
    Index created.
    SQL> exec dbms_stats.gather_table_stats(user,'A');
    SQL>  explain plan for select from a where object_id = 1;*
    Explained.
    SQL> select from table(dbms_xplan.display());*
    PLAN_TABLE_OUTPUT
    Plan hash value: 3632291705
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    PLAN_TABLE_OUTPUT
    | 0 | SELECT STATEMENT | | 1 | 11 | 2 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| A | 1 | 11 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | A_IDX | 1 | | 1 (0)| 00:00:01 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
    2 - access("OBJECT_ID"=1)
    SQL> set autot on
    SQL> select * from a where object_id = 1;
    no rows selected
    Execution Plan
    Plan hash value: 3632291705
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 11 | 2 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| A | 1 | 11 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | A_IDX | 1 | | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - access("OBJECT_ID"=1)
    Statistics
    1 recursive calls
    0 db block gets
    1 consistent gets
    0 physical reads
    0 redo size
    395 bytes sent via SQL*Net to client
    481 bytes received via SQL*Net from client
    1 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    0 rows processed
    SQL> exec dbms_monitor.session_trace_enable(null,null,true,true);
    -- SQL> alter session set events '10046 trace name context forever, level 12';
    -- SQL> alter session set sql_trace = true;
    PL/SQL procedure successfully completed.
    SQL> select * from a where object_id = 1;
    no rows selected
    * SQL> exec dbms_monitor.session_trace_disable(null, null);*
    -- SQL> alter session set events '10046 trace name context off';
    -- SQL> alter session set sql_trace = false;
    PL/SQL procedure successfully completed.
    SQL> show parameter user_dump_dest
    */home/oracle/admin/WASDB/udump*
    SQL>host
    JOSS:oracle:/home/oracle:!> cd /home/oracle/admin/WASDB/udump
    JOSS:oracle:/home/oracle/admin/WASDB/udump:!> ls -lrt
    -rw-r----- 1 oracle dba 2481 Oct 11 16:38 wasdb_ora_21745.trc
    JOSS:oracle:/home/oracle/admin/WASDB/udump:!> tkprof wasdb_ora_21745.trc trc.out
    TKPROF: Release 10.2.0.3.0 - Production on Thu Oct 11 16:40:44 2007
    Copyright (c) 1982, 2005, Oracle. All rights reserved.
    JOSS:oracle:/home/oracle/admin/WASDB/udump:!> vi trc.out
    select *
    from
    a where object_id = 1
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 0.00 0.00 0 0 0 0
    Fetch 1 0.00 0.00 0 1 0 0
    total 3 0.00 0.00 0 1 0 0
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 55
    Rows Row Source Operation
    0 TABLE ACCESS BY INDEX ROWID A (cr=1 pr=0 pw=0 time=45 us)
    0 INDEX RANGE SCAN A_IDX (cr=1 pr=0 pw=0 time=39 us)(object id 65441)
    Elapsed times include waiting on following events:
    Event waited on Times Max. Wait Total Waited
    ---------------------------------------- Waited ---------- ------------
    SQL*Net message to client 1 0.00 0.00
    SQL*Net message from client 1 25.01 25.01
    Hope this helps

  • INTERMEDIA TEXT INDEX를 사용하는 QUERY의 TUNING

    제품 : ORACLE SERVER
    작성날짜 : 2002-04-12
    INTERMEDIA TEXT INDEX를 사용하는 QUERY의 TUNING
    ===============================================
    Purpose
    Intermedia text를 사용하는 query의 속도를 향상시킬 수 있는 방안을
    알아보자.
    Explanation
    1. Make analyze all the table in the query
    text index를 이용하는 Query 안의 모든 Table을 analyze 해 주십시요.
    예를 들어 다음의 command를 이용할 수 있습니다.
    ANALYZE TABLE <table_name> COMPUTE STATISTICS;
    or
    ANALYZE TABLE <table_name> ESTIMATE STATISTICS 1000 ROWS;
    or
    ANALYZE TABLE <table_name> ESTIMATE STATISTICS 50 PERCENT;
    2. Using FIRST_ROWS hint
    더 좋은 response time 을 위해서 first_rows hint 를 사용해 보십시요.
    database에 기본적으로 설정된 optimizer mode는 choose mode입니다.
    이것은 전체 처리시간(throughput)을 가장 빠르게 하기 위한(all_rows mode)
    plan을 따르기 때문에 user의 입장에서는 first_rows 보다는 늦다고 느낄 수
    있습니다.
    Query에 다음과 같이 hint를 주고 performance를 확인해 보십시요.
    select /*+ FIRST_ROWS */ pk, col from ctx_tab
    where contains(txt_col, 'test', 1) > 0;
    단, first_rows hint를 이용하는 경우 자동으로 score 순서대로
    ordering 되지 않습니다. 왜냐하면 단어에 부합하는 문서를 찾는대로
    즉시 결과로 나타내 주기 때문입니다.
    3. Make sure text index is not fragmented
    insert, delete 가 많이 되는 table의 경우 index fragment를 제거해 주어야
    합니다. Index fragmentation 은 다음과 같이 확인할 수 있습니다.
    select count(*) from dr$<indexname>$i; -> A
    select count(*) from (select distinct(token_text) from dr$<indexname>$i); -> B
    위의 결과가 A/B 의 값이 3:1 보다 크면 optimize_index 를 실행해 주시는
    것이 좋습니다. 다음과 같은 command로 index optimization을 할 수 있습니다.
    alter index <index_name> rebuild online
    parameters('optimize full unlimited');
    index rebuild중에 online option을 주면 rebuild하는 중에도 계속 index를
    사용할 수 있게 됩니다. 하지만, 가능하면 사용자가 없을 때 rebuild하는 것이
    좋습니다.
    4. Check execution plan and sql trace.
    기본적인 여러 가지 작업들에도 속도가 별로 향상되지 않는다면, 직접
    sql trace를 떠서 Execution plan등을 확인해 보는 것이 필요합니다.
    예를 들어 SQL*PLUS에서 다음과 같이 sql trace를 뜹니다.
    alter session set timed_statistics=true;
    alter session set sql_trace=true;
    select ..... -> execute the query
    실행 후,
    exit
    user_dump_dest 에 지정된 directory에 trace 가 떨어지면 다음과 같은
    command로 tkprof 를 떠서 내용을 확인합니다.
    $ tkprof <tracefilename> <outputfilename> explain=username/password
    Referenc Documents
    Bulletin#10134 : SQL trace와 tkprof 사용 방법

  • RE:Query Tuning

    Hi,
    Oracle :10.2.0.1
    I am trying to learn query tuning.
    Am using the document
    http://www.oracle.com/pls/db10g/db10g.show_toc?which=main&partno=b10752&maxlevel=2§ion=&expand=49346
    And i tried using the query which is in the document
    SELECT e.emp_id, e.f_name, e.l_name, e.dept_id, e.sal
        FROM EMPLOYEES e
       WHERE e.dept_id = 81                                   
         AND e.job_id        = 'SA_REP'                         
         AND e.emp_id IN (SELECT o.rep_id FROM ORDERS o)  Am using explain plan for this query to measure the cost it shows
    Operation               Object Name          Rows     Bytes     Cost     Object Node     In/Out     PStart     PStop
    SELECT STATEMENT Optimizer Mode=ALL_ROWS          1 K           41                                          
      HASH JOIN SEMI                         1 K     243 K     41                                          
        TABLE ACCESS FULL          SCOTT.EMPLOYEES          1 K     227 K     26                                          
        INDEX FAST FULL SCAN     SCOTT.NUIDX_REP_ID     26 K     335 K     14                                           And then i tried using EXISTS clause which is recomended in the document
    SELECT /* EXISTS example */
             e.employee_id, e.first_name, e.last_name, e.salary
        FROM employees e
       WHERE e.department_id = 80                           /* Note 5 */
         AND e.job_id        = 'SA_REP'                     /* Note 6 */
         AND EXISTS (SELECT 1                               /* Note 1 */
                       FROM orders o
                      WHERE e.employee_id = o.sales_rep_id);  /* Note 2 */Am using explain plan for this query too, to measure the cost it shows
    Operation               Object Name          Rows     Bytes     Cost     Object Node     In/Out     PStart     PStop
    SELECT STATEMENT Optimizer Mode=ALL_ROWS          206             41                                          
      HASH JOIN SEMI                         206       6 K     41                                          
        TABLE ACCESS FULL          SCOTT.EMPLOYEES     206       3 K          25                                          
        INDEX FAST FULL SCAN     SCOTT.NUIDX_REP_ID     26 K     335 K     14                                           I dont know how to judge the query performance because the cost's of those two queries are more are less same...
    I am a bit confused, plz advice how to judge the queries performace using explain plan...
    TIA,

    In addition to what SomeoneElse said, unless you made a cut and paste error, the two plans are actually identical. This is one of the cases where the optimizer re-wrote an exists as ain in (the Hash-Join Semi). So, the plan being executed would be the same for both. Therefore I would not expect to see any significant performance difference between the two queries.
    John

  • Ebooks on SQL Query tuning

    HI.
    can somebody post me any links for ebooks on SQL Query tuning techniques for either 10g or 11g.
    Tuning SQL Queries is something I would like to build my expertise on..
    There may be a lot of advisors like SQL Query Advisor, Access Advisor and so on...but nothing like tuning your queries manually to maximum optimization.
    Kindly help me in this !!

    Check Oracle docs http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/toc.htm
    But you should really also be checking:
    http://www.asktom.oracle.com
    http://tkyte.blogspot.com
    AND all other blogs he referres to ( like Jonathan Lewis' site and blog ) you'll find many interesting articles over there, from 'the real world', regarding performance and tuning.
    Edited by: hoek on Mar 24, 2009 10:40 AM

  • Performance tuning or Query tuning

    Hi,
    I am a PL/SQL programmer and I wanna learn Query tuning or performance tuning to extend my knowledge.
    Can any one please suggest me where to start? I read somthing RBO and CBO and get into confusion is oracle supports both? which one is better? how to use them...is it differ from version to version like 9i/10g
    I appreciate any kind of help.
    Thanks and Regards
    Mai

    Hi,
    If you a pl/sql programmer than I shall assume that you don't do much database activity and at the moment , would be upgrading yourself with the database knowledge. I shall suggest in addition to Oracle docs, these books in order to understand Query Tuning.
    Effective-Oracle-By-Design
    Cost-Based-Oracle-Fundamentals
    Practical-Oracle8i
    I have found these books as the best ones in the understandng of various very important factors in query tuning and I use these books every day.
    HTH
    Aman....

  • Query on using Variables in Oracle Query

    Hi
    i am new to Oracle, i have tried extracting data from the Oracle Database using the following Query which includes 1 variable SYSDATE_UTS, however when i try to execute the Query i get an error. Please let me know what am i doing wrong and how can i correct it.
    Error Message
    ORA-06550: line 4, column 1:
    PLS-00428: an INTO clause is expected in this SELECT statement
    Oracle Query
    DECLARE SYSDATE_UTS NUMBER := (sysdate-to_date('19700101','yyyymmdd'))*86400;
    BEGIN
    SELECT
    INCIDENT_NUMBER,
    to_date(to_char((1/86400*REPORTED_DATE)+to_date('19700101','yyyymmdd'),'mm/dd/yyyy hh24:mi:ss'),'mm/dd/yyyy hh24:mi:ss') as REPORTED_DATE_TIME,
    ,GROUP_TRANSFERS
    ,LAST_MODIFIED_BY
    ,to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * LAST_MODIFIED_DATE,'mm/dd/yyyy hh24:mi:ss'),'mm/dd/yyyy hh24:mi:ss') as LAST_MODIFIED_DATE
    ,(to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) as AGE
    ,CASE
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 0 AND 1 THEN '0-1 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS, 'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 2 AND 4 THEN '2-4 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 5 AND 9 THEN '5-9 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 10 AND 19 THEN '10-19 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) >20 THEN '20+ Days'
    ELSE 'UNKNOWN'
    END AS AGE_GROUP
    FROM IncidentDataBase
    and STATUS not in (4,5,6)
    and rownum <10;
    END;

    Hi Frank
    i am using the following Oracle Version
    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
    PL/SQL Release 10.2.0.5.0 - Production
    CORE     10.2.0.5.0     Production
    TNS for Linux: Version 10.2.0.5.0 - Production
    NLSRTL Version 10.2.0.5.0 - Production
    and Quest Toad for Oracle to write and execute the queries:
    Toad for Oracle Xpert
    Version 10.1.1.8
    The code i am using is:
    variable SYSDATE_UTS NUMBER;
    exec SYSDATE_UTS := (sysdate-to_date('19700101','yyyymmdd'))*86400;
    SELECT
    INCIDENT_NUMBER,
    to_date(to_char((1/86400*REPORTED_DATE)+to_date('19700101','yyyymmdd'),'mm/dd/yyyy hh24:mi:ss'),'mm/dd/yyyy hh24:mi:ss') as REPORTED_DATE_TIME
    ,GROUP_TRANSFERS
    ,LAST_MODIFIED_BY
    ,to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * LAST_MODIFIED_DATE,'mm/dd/yyyy hh24:mi:ss'),'mm/dd/yyyy hh24:mi:ss') as LAST_MODIFIED_DATE
    ,(to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) as AGE
    ,CASE
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 0 AND 1 THEN '0-1 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS, 'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 2 AND 4 THEN '2-4 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 5 AND 9 THEN '5-9 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) BETWEEN 10 AND 19 THEN '10-19 Days'
    WHEN (to_date(to_char(to_date('01011970','ddmmyyyy')+1/24/60/60 * :SYSDATE_UTS,'mm/dd/yyyy'),'mm/dd/yyyy')) - (to_date(to_char(+to_date('19700101','yyyymmdd')+1/86400*REPORTED_DATE,'mm/dd/yyyy'),'mm/dd/yyyy')) >20 THEN '20+ Days'
    ELSE 'UNKNOWN'
    END AS AGE_GROUP
    FROM IncidentDataBase
    WHERE STATUS not in (4,5,6)
    and rownum <10;
    Notes:
    1. When i put the cursor before "variable" (starting of the query) and execute the script i get an Error: ORA-00900: invalid SQL statement.
    2. When i put the cursor just before "SELECT" i get a pop up.
    a. it is a Toad window which displays the available variables (in this case :SYSDATE_UTS).
    b. gives me a dropdown option to select the type (by default VARCHAR2 is selected).
    c. there is a value field where i need to enter the value for the Variable.
    d. the SQL statement shown in this dilog box does not include the 1st 2 lines
    variable SYSDATE_UTS NUMBER;
    exec SYSDATE_UTS := (sysdate-to_date('19700101','yyyymmdd'))*86400;
    Q: is there something wrong in the syntax i am using?
    Sven W. - I have been using your method all these days, which works just fine. i wanted to know how i could use a variable instead.
    Business Requirement - My whole intent is to calculate the Age of an incident (Difference between "Reported Date" and current date) and to assign Age Groups (0-1 Days, 2-4 Days,....,20+ Days).
    Edited by: 921713 on Mar 19, 2012 12:23 PM

Maybe you are looking for

  • ISO: solution for these itunes vs windows vista home premium problems?

    1.Every time I start itunes, it tells me that there are registry entries missing for burning a disk and something else that escapes my immediate memory. However, it suggests reinstalling itunes and I've done that many times without the problem going

  • Purchase order IDOC: output

    Hi I did configure a the following. 1.Outbound message type <b>ORDERS</b> 2.Outbound receiver port : TRfc 3.Basictype <b>ORDERS05</b> 4.Message control: Application <b>EF</b> Message type <b>NEU</b> . Process code <u>ME10</u> What do i need to config

  • Help with SSL SOCKETS

    hi, i seem to have a problem with establishing an ssl socket between 2 machines. This problem has to do with certificates as the runtime error i get specifies. So i figured out there must be a concept that i'm misssing. So why do i have to place a ce

  • Narrative Report - default to A4 print size

    Hi, I need to build a form using the narrative report and the report should fit into A4 printable size. These are the steps I performed" First I design the form using excel and I have ensure that the form does fit into A4 print size(check via print p

  • Modify the text of a data field on the screen

    Hi, I am looking to change the text of a  SAP data field on the display screen for an infotype 106. I have the required object key for it. When I entered the key it logged me successfully, however it displayed a message that I am not authroized for c