Cbo plan

Pls tell me how the execution plan execute in CBO.
from RBO Is right to left.
I am runing one query is RBO as well as CBO Plan is different
sequence of table access is different.
Thanks
Reena

Hi,
which version of Oracle are you runnning,
In CBO the optimizer will determine the driving table. The CBO will determine upon the COST which will be the driving table which will be derermined by the INDEXES, the Statistics of the table and other parameters.
Where as in RBO the table from the right in the FORM clause will be the driving table.
thanks

Similar Messages

  • SQL Tunning

    I am having one batch job in which query fatching data from various tables and inserting in one table.
    It's taking 3-4 hours. On generating explain plan i come to know that query taking more time due to one outer join between one view(say V1) and large table(say T1).
    V1.Column(+) =T1.Column1 || '-' || T1.Column2
    If i remove this outer join it will improve but according to need i can't do it.
    It's oracle8i and its using rule based only
    I am planning to create 2 Indexed. 1 on T1.Column1 and other T1.Column2. or any other suggestion from you guys.
    It's very urgent i need to do it in 2 days. Please any one help me out
    Thanks in advance
    Chetan

    ChetanS wrote:
    This is my tkprof result
    call count cpu elapsed disk query current rows
    Parse 1 12.24 12.26 0 0 2 0
    Execute 1 0.01 0.02 0 3 9 0
    Fetch 438 48.54 153.05 43263 917910 241 438000
    total 440 60.79 165.33 43263 917913 252 438000
    See below explain plan
    you find more cost due to above joinI'm not sure how to interpret your posts. A few comments:
    1. You said you're using 8i with rule based optimization. But now you're talking about cost and the plan shows a cost, too. So it looks more like a CBO plan.
    2. If you say that "If i remove this outer join it will improve but according to need i can't do it.", what do you mean exactly?
    - Turn the the outer join into an inner join?
    - Remove the join clause completely?
    And what do you mean by "it will improve"? Does it perform better, or do you get simply a lower cost returned by EXPLAIN PLAN?
    3. The plan looks convoluted. There are REMOTE objects involved and the DUAL table is referenced multiple times, so it might a very good idea to share the actual query code used. If required, mask the table/view names and replace them with "table1/2/3" etc.
    Note that the optimizer often does a suboptimal job when REMOTE objects are involved, so may be this is one of the root causes of your performance issues.
    4. Use the \ tag before and after text that should be formatted in fixed font for better readability. Use the "Quote" button in the message editor to see how I did it here.
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Why was RBO used?

    Oracle 11.1.0.7.
    spfile - optimizer_mode = ALL_ROWS. optimizer_features_enable = 11.1.0.7.
    Auto stats gathering jobs are all enabled. So everything should be all CBO all the way.
    Some queries were mysteriously slow on Friday. Digging into AWR stats finally revealed that a SQL statement (sql_id) had spawned a plan_hash_value that was the culprit. It was doing a full table scan on a large table and consuming a lot of CPU/IO. Dumping out everything AWR knows about this SQL using
    select * from table(dbms_xplan.display_awr('45knuy45ha5f2',NULL,NULL,'ADVANCED'))Pored over the output and sure enough, the "bad" plan_hash_value was using the FTS and the Note in the output said "rule based optimizer used (consider using cbo)".
    I couldn't believe my eyes. Why in the world did that one child cursor use the RBO?
    Any ideas?

    Karthick - No. The query is coming from a application so the query and session parameters are fixed. As AWR shows, the query was executed dozens of times and all the plan_hash_values for the same sql_id use CBO, just this one bad apple used the RBO. Why?
    Hoek - Yes, I read all of Kerry Osborne's excellent blog entries, that's how I narrowed down the problem to this particular sql_id. But it doesn't talk about WHY a particular query would use the RBO. The most common culprit, bind variable peeking, may cause the plan to flip between 2 CBO plans but it shouldn't cause the RBO to be used.
    Martin - That's what I thought too but all objects used in the query do have stats. Since the Oracle auto-stats job/task is running daily, stats are always up-to-date. Here are all the optimizer* parameters in the spfile.
    This is really frustrating.
    optimizer_features_enable     11.1.0.7
    optimizer_mode     ALL_ROWS
    optimizer_index_cost_adj     100
    optimizer_index_caching     0
    optimizer_dynamic_sampling     2
    optimizer_secure_view_merging     TRUE
    optimizer_use_pending_statistics     FALSE
    optimizer_capture_sql_plan_baselines     FALSE
    optimizer_use_sql_plan_baselines     TRUE
    optimizer_use_invisible_indexes     FALSE[Oracle Support is looking into it but they usually ask for a 10046 trace and we can't provide that because AWR doesn't capture that and the issue is not reproducible at-will]

  • CBO generating different plans for the same data in similar Environments

    Hi All
    I have been trying to compare an SQL from 2 different but similar environments build of the same hardware specs .The issue I am facing is environment A, the query executes in less than 2 minutes with plan mostly showing full table scans and hash join whereas in environment B(problematic), it times out after 2 hours with an error of unable to extend table space . The statistics are up to date in both environments for both tables and indexes . System parameters are exactly similar(default oracle for except for multiblock_read_count ).
    Both Environment have same db parameter for db_file_multiblock_read_count(16), optimizer(refer below),hash_area_size (131072),pga_aggregate_target(1G),db_block_size(8192) etc . SREADTIM, MREADTIM, CPUSPEED, MBRC are all null in aux_stats in both environment because workload was never collected i believe.
    Attached is details about the SQL with table stats, SQL and index stats my main concern is CBO generating different plans for the similar data and statistics and same hardware and software specs. Is there any thing else I should consider .I generally see environment B being very slow and always plans tend to nested loops and index scan whereas what we really need is a sensible FTS in many cases. One of the very surprising thing is METER_CONFIG_HEADER below which has just 80 blocks of data is being asked for index scan.
    show parameter optimizer
    optimizer_dynamic_sampling integer 2
    optimizer_features_enable string 10.2.0.4
    optimizer_index_caching integer 0
    optimizer_index_cost_adj integer 100
    optimizer_mode string ALL_ROWS
    optimizer_secure_view_merging boolean TRUE
    **Environment**
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE     10.2.0.4.0     Production
    TNS for Solaris: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    Note: : There are slight difference in the no of records in the attached sheet.However, I wanted to tell that i have tested with exact same data and was getting similar results but I couldn't retain the data untill collecting the details in the attachment
    TEST1     COMPARE TABLE LEVE STATS  used by CBO          
    ENVIRONMENT A
    TABLE_NAME     NUM_ROWS     BLOCKS     LAST_ANALYZED
    ASSET     3607425     167760     5/02/2013 22:11
    METER_CONFIG_HEADER     3658     80     5/01/2013 0:07
    METER_CONFIG_ITEM     32310     496     5/01/2013 0:07
    NMI     1899024     33557     18/02/2013 10:55
    REGISTER     4830153     101504     18/02/2013 9:57
    SDP_LOGICAL_ASSET     1607456     19137     18/02/2013 15:48
    SDP_LOGICAL_REGISTER     5110781     78691     18/02/2013 9:56
    SERVICE_DELIVERY_POINT     1425890     42468     18/02/2013 13:54
    ENVIRONMENT B
    TABLE_NAME     NUM_ROWS     BLOCKS     LAST_ANALYZED
    ASSET     4133939     198570     16/02/2013 10:02
    METER_CONFIG_HEADER     3779     80     16/02/2013 10:55
    METER_CONFIG_ITEM     33720     510     16/02/2013 10:55
    NMI     1969000     33113     16/02/2013 10:58
    REGISTER     5837874     120104     16/02/2013 11:05
    SDP_LOGICAL_ASSET     1788152     22325     16/02/2013 11:06
    SDP_LOGICAL_REGISTER     6101934     91088     16/02/2013 11:07
    SERVICE_DELIVERY_POINT     1447589     43804     16/02/2013 11:11
    TEST ITEM 2     COMPARE INDEX STATS  used by CBO          
    ENVIRONMENT A
    TABLE_NAME     INDEX_NAME     UNIQUENESS     BLEVEL     LEAF_BLOCKS     DISTINCT_KEYS     AVG_LEAF_BLOCKS_PER_KEY     AVG_DATA_BLOCKS_PER_KEY     CLUSTERING_FACTOR     NUM_ROWS
    ASSET     IDX_AST_DEVICE_CATEGORY_SK     NONUNIQUE     2     9878     67     147     12982     869801     3553095
    ASSET     IDX_A_SAPINTLOGDEV_SK     NONUNIQUE     2     7291     2747     2     639     1755977     3597916
    ASSET     SYS_C00102592     UNIQUE     2     12488     3733831     1     1     3726639     3733831
    METER_CONFIG_HEADER     SYS_C0092052     UNIQUE     1     12     3670     1     1     3590     3670
    METER_CONFIG_ITEM     SYS_C0092074     UNIQUE     1     104     32310     1     1     32132     32310
    NMI     IDX_NMI_ID     NONUNIQUE     2     6298     844853     1     2     1964769     1965029
    NMI     IDX_NMI_ID_NK     NONUNIQUE     2     6701     1923072     1     1     1922831     1923084
    NMI     IDX_NMI_STATS     NONUNIQUE     1     106     4     26     52     211     211
    REGISTER     REG_EFFECTIVE_DTM     NONUNIQUE     2     12498     795     15     2899     2304831     4711808
    REGISTER     SYS_C00102653     UNIQUE     2     16942     5065660     1     1     5056855     5065660
    SDP_LOGICAL_ASSET     IDX_SLA_SAPINTLOGDEV_SK     NONUNIQUE     2     3667     1607968     1     1     1607689     1607982
    SDP_LOGICAL_ASSET     IDX_SLA_SDP_SK     NONUNIQUE     2     3811     668727     1     2     1606204     1607982
    SDP_LOGICAL_ASSET     SYS_C00102665     UNIQUE     2     5116     1529606     1     1     1528136     1529606
    SDP_LOGICAL_REGISTER     SYS_C00102677     UNIQUE     2     17370     5193638     1     1     5193623     5193638
    SERVICE_DELIVERY_POINT     IDX_SDP_NMI_SK     NONUNIQUE     2     4406     676523     1     2     1423247     1425890
    SERVICE_DELIVERY_POINT     IDX_SDP_SAP_INT_NMI_SK     NONUNIQUE     2     7374     676523     1     2     1458238     1461108
    SERVICE_DELIVERY_POINT     SYS_C00102687     UNIQUE     2     4737     1416207     1     1     1415022     1416207
    ENVIRONMENT B
    TABLE_NAME     INDEX_NAME     UNIQUENESS     BLEVEL     LEAF_BLOCKS     DISTINCT_KEYS     AVG_LEAF_BLOCKS_PER_KEY     AVG_DATA_BLOCKS_PER_KEY     CLUSTERING_FACTOR     NUM_ROWS
    ASSET     IDX_AST_DEVICE_CATEGORY_SK     NONUNIQUE     2     8606     121     71     16428     1987833     4162257
    ASSET     IDX_A_SAPINTLOGDEV_SK     NONUNIQUE     2     8432     1780146     1     1     2048170     4162257
    ASSET     SYS_C00116157     UNIQUE     2     13597     4162263     1     1     4158759     4162263
    METER_CONFIG_HEADER     SYS_C00116570     UNIQUE     1     12     3779     1     1     3734     3779
    METER_CONFIG_ITEM     SYS_C00116592     UNIQUE     1     107     33720     1     1     33459     33720
    NMI     IDX_NMI_ID     NONUNIQUE     2     6319     683370     1     2     1970460     1971313
    NMI     IDX_NMI_ID_NK     NONUNIQUE     2     6597     1971293     1     1     1970771     1971313
    NMI     IDX_NMI_STATS     NONUNIQUE     1     98     48     2     4     196     196
    REGISTER     REG_EFFECTIVE_DTM     NONUNIQUE     2     15615     1273     12     2109     2685924     5886582
    REGISTER     SYS_C00116748     UNIQUE     2     19533     5886582     1     1     5845565     5886582
    SDP_LOGICAL_ASSET     IDX_SLA_SAPINTLOGDEV_SK     NONUNIQUE     2     4111     1795084     1     1     1758441     1795130
    SDP_LOGICAL_ASSET     IDX_SLA_SDP_SK     NONUNIQUE     2     4003     674249     1     2     1787987     1795130
    SDP_LOGICAL_ASSET     SYS_C004520     UNIQUE     2     5864     1795130     1     1     1782147     1795130
    SDP_LOGICAL_REGISTER     SYS_C004539     UNIQUE     2     20413     6152850     1     1     6073059     6152850
    SERVICE_DELIVERY_POINT     IDX_SDP_NMI_SK     NONUNIQUE     2     3227     660649     1     2     1422572     1447803
    SERVICE_DELIVERY_POINT     IDX_SDP_SAP_INT_NMI_SK     NONUNIQUE     2     6399     646257     1     2     1346948     1349993
    SERVICE_DELIVERY_POINT     SYS_C00128706     UNIQUE     2     4643     1447946     1     1     1442796     1447946
    TEST ITEM 3     COMPARE PLANS     
    ENVIRONMENT A
    Plan hash value: 4109575732                                             
    | Id  | Operation                       | Name                   | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                                             
    |   0 | SELECT STATEMENT                |                        |    13 |  2067 |       |   135K  (2)| 00:27:05 |                                             
    |   1 |  HASH UNIQUE                    |                        |    13 |  2067 |       |   135K  (2)| 00:27:05 |                                             
    |*  2 |   HASH JOIN                     |                        |    13 |  2067 |       |   135K  (2)| 00:27:05 |                                             
    |*  3 |    HASH JOIN                    |                        |     6 |   900 |       |   135K  (2)| 00:27:04 |                                             
    |*  4 |     HASH JOIN ANTI              |                        |     1 |   137 |       |   135K  (2)| 00:27:03 |                                             
    |*  5 |      TABLE ACCESS BY INDEX ROWID| NMI                    |     1 |    22 |       |     5   (0)| 00:00:01 |                                             
    |   6 |       NESTED LOOPS              |                        |     1 |   131 |       | 95137   (2)| 00:19:02 |                                             
    |*  7 |        HASH JOIN                |                        |     1 |   109 |       | 95132   (2)| 00:19:02 |                                             
    |*  8 |         TABLE ACCESS FULL       | ASSET                  | 36074 |  1021K|       | 38553   (2)| 00:07:43 |                                             
    |*  9 |         HASH JOIN               |                        | 90361 |  7059K|  4040K| 56578   (2)| 00:11:19 |                                             
    |* 10 |          HASH JOIN              |                        | 52977 |  3414K|  2248K| 50654   (2)| 00:10:08 |                                             
    |* 11 |           HASH JOIN             |                        | 39674 |  1782K|       | 40101   (2)| 00:08:02 |                                             
    |* 12 |            TABLE ACCESS FULL    | REGISTER               | 39439 |  1232K|       | 22584   (2)| 00:04:32 |                                             
    |* 13 |            TABLE ACCESS FULL    | SDP_LOGICAL_REGISTER   |  4206K|    56M|       | 17490   (2)| 00:03:30 |                                             
    |* 14 |           TABLE ACCESS FULL     | SERVICE_DELIVERY_POINT |   675K|    12M|       |  9412   (2)| 00:01:53 |                                             
    |* 15 |          TABLE ACCESS FULL      | SDP_LOGICAL_ASSET      |  1178K|    15M|       |  4262   (2)| 00:00:52 |                                             
    |* 16 |        INDEX RANGE SCAN         | IDX_NMI_ID_NK          |     2 |       |       |     2   (0)| 00:00:01 |                                             
    |  17 |      VIEW                       |                        | 39674 |   232K|       | 40101   (2)| 00:08:02 |                                             
    |* 18 |       HASH JOIN                 |                        | 39674 |  1046K|       | 40101   (2)| 00:08:02 |                                             
    |* 19 |        TABLE ACCESS FULL        | REGISTER               | 39439 |   500K|       | 22584   (2)| 00:04:32 |                                             
    |* 20 |        TABLE ACCESS FULL        | SDP_LOGICAL_REGISTER   |  4206K|    56M|       | 17490   (2)| 00:03:30 |                                             
    |* 21 |     TABLE ACCESS FULL           | METER_CONFIG_HEADER    |  3658 | 47554 |       |    19   (0)| 00:00:01 |                                             
    |* 22 |    TABLE ACCESS FULL            | METER_CONFIG_ITEM      |  7590 | 68310 |       |   112   (2)| 00:00:02 |                                             
    Predicate Information (identified by operation id):                                             
       2 - access("METER_CONFIG_HEADER_SK"="METER_CONFIG_HEADER_SK")                                             
       3 - access("NETWORK_TARIFF_CD"="NETWORK_TARIFF_CD")                                             
       4 - access("SERVICE_DELIVERY_POINT_SK"="TMP"."SERVICE_DELIVERY_POINT_SK")                                             
       5 - filter("ROW_CURRENT_IND"='Y' AND ("NMI_STATUS_CD"='A' OR "NMI_STATUS_CD"='D'))                                             
       7 - access("ASSET_CD"="EQUIP_CD" AND "SAP_INT_LOG_DEVICE_SK"="SAP_INT_LOG_DEVICE_SK")                                             
       8 - filter("ROW_CURRENT_IND"='Y')                                             
       9 - access("SERVICE_DELIVERY_POINT_SK"="SERVICE_DELIVERY_POINT_SK")                                             
      10 - access("SERVICE_DELIVERY_POINT_SK"="SERVICE_DELIVERY_POINT_SK")                                             
      11 - access("SAP_INT_LOGICAL_REGISTER_SK"="SAP_INT_LOGICAL_REGISTER_SK")                                             
      12 - filter("REGISTER_TYPE_CD"='C' AND (SUBSTR("REGISTER_ID_CD",1,1)='4' OR                                              
                  SUBSTR("REGISTER_ID_CD",1,1)='5' OR SUBSTR("REGISTER_ID_CD",1,1)='6') AND "ROW_CURRENT_IND"='Y')                                             
      13 - filter("ROW_CURRENT_IND"='Y')                                             
      14 - filter("ROW_CURRENT_IND"='Y')                                             
      15 - filter("ROW_CURRENT_IND"='Y')                                             
      16 - access("NMI_SK"="NMI_SK")                                             
      18 - access("SAP_INT_LOGICAL_REGISTER_SK"="SAP_INT_LOGICAL_REGISTER_SK")                                             
      19 - filter("REGISTER_TYPE_CD"='C' AND (SUBSTR("REGISTER_ID_CD",1,1)='1' OR                                              
                  SUBSTR("REGISTER_ID_CD",1,1)='2' OR SUBSTR("REGISTER_ID_CD",1,1)='3') AND "ROW_CURRENT_IND"='Y')                                             
      20 - filter("ROW_CURRENT_IND"='Y')                                             
      21 - filter("ROW_CURRENT_IND"='Y')                                             
      22 - filter("ROW_CURRENT_IND"='Y' AND "CONROL_REGISTER"='X')                                             
    ENVIRONMENT B
    Plan hash value: 2826260434                                   
    | Id  | Operation                            | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |                                   
    |   0 | SELECT STATEMENT                     |                        |     1 |   181 |   103K  (2)| 00:20:47 |                                   
    |   1 |  HASH UNIQUE                         |                        |     1 |   181 |   103K  (2)| 00:20:47 |                                   
    |*  2 |   HASH JOIN ANTI                     |                        |     1 |   181 |   103K  (2)| 00:20:47 |                                   
    |*  3 |    HASH JOIN                         |                        |     1 |   176 | 56855   (2)| 00:11:23 |                                   
    |*  4 |     HASH JOIN                        |                        |     1 |   163 | 36577   (2)| 00:07:19 |                                   
    |*  5 |      TABLE ACCESS BY INDEX ROWID     | ASSET                  |     1 |    44 |     4   (0)| 00:00:01 |                                   
    |   6 |       NESTED LOOPS                   |                        |     1 |   131 |  9834   (2)| 00:01:59 |                                   
    |   7 |        NESTED LOOPS                  |                        |     1 |    87 |  9830   (2)| 00:01:58 |                                   
    |   8 |         NESTED LOOPS                 |                        |     1 |    74 |  9825   (2)| 00:01:58 |                                   
    |*  9 |          HASH JOIN                   |                        |     1 |    52 |  9820   (2)| 00:01:58 |                                   
    |* 10 |           TABLE ACCESS BY INDEX ROWID| METER_CONFIG_HEADER    |     1 |    14 |     1   (0)| 00:00:01 |                                   
    |  11 |            NESTED LOOPS              |                        |     1 |    33 |   116   (2)| 00:00:02 |                                   
    |* 12 |             TABLE ACCESS FULL        | METER_CONFIG_ITEM      |     1 |    19 |   115   (2)| 00:00:02 |                                   
    |* 13 |             INDEX RANGE SCAN         | SYS_C00116570          |     1 |       |     1   (0)| 00:00:01 |                                   
    |* 14 |           TABLE ACCESS FULL          | SERVICE_DELIVERY_POINT |   723K|    13M|  9699   (2)| 00:01:57 |                                   
    |* 15 |          TABLE ACCESS BY INDEX ROWID | NMI                    |     1 |    22 |     5   (0)| 00:00:01 |                                   
    |* 16 |           INDEX RANGE SCAN           | IDX_NMI_ID_NK          |     2 |       |     2   (0)| 00:00:01 |                                   
    |* 17 |         TABLE ACCESS BY INDEX ROWID  | SDP_LOGICAL_ASSET      |     1 |    13 |     5   (0)| 00:00:01 |                                   
    |* 18 |          INDEX RANGE SCAN            | IDX_SLA_SDP_SK         |     2 |       |     2   (0)| 00:00:01 |                                   
    |* 19 |        INDEX RANGE SCAN              | IDX_A_SAPINTLOGDEV_SK  |     2 |       |     2   (0)| 00:00:01 |                                   
    |* 20 |      TABLE ACCESS FULL               | REGISTER               | 76113 |  2378K| 26743   (2)| 00:05:21 |                                   
    |* 21 |     TABLE ACCESS FULL                | SDP_LOGICAL_REGISTER   |  5095K|    63M| 20245   (2)| 00:04:03 |                                   
    |  22 |    VIEW                              |                        | 90889 |   443K| 47021   (2)| 00:09:25 |                                   
    |* 23 |     HASH JOIN                        |                        | 90889 |  2307K| 47021   (2)| 00:09:25 |                                   
    |* 24 |      TABLE ACCESS FULL               | REGISTER               | 76113 |   966K| 26743   (2)| 00:05:21 |                                   
    |* 25 |      TABLE ACCESS FULL               | SDP_LOGICAL_REGISTER   |  5095K|    63M| 20245   (2)| 00:04:03 |                                   
    Predicate Information (identified by operation id):                                   
       2 - access("SERVICE_DELIVERY_POINT_SK"="TMP"."SERVICE_DELIVERY_POINT_SK")                                   
       3 - access("SERVICE_DELIVERY_POINT_SK"="SERVICE_DELIVERY_POINT_SK" AND                                    
                  "SAP_INT_LOGICAL_REGISTER_SK"="SAP_INT_LOGICAL_REGISTER_SK")                                   
       4 - access("ASSET_CD"="EQUIP_CD")                                   
       5 - filter("ROW_CURRENT_IND"='Y')                                   
       9 - access("NETWORK_TARIFF_CD"="NETWORK_TARIFF_CD")                                   
      10 - filter("ROW_CURRENT_IND"='Y')                                   
      12 - filter("ROW_CURRENT_IND"='Y' AND "CONROL_REGISTER"='X')                                   
      13 - access("METER_CONFIG_HEADER_SK"="METER_CONFIG_HEADER_SK")                                   
      14 - filter("ROW_CURRENT_IND"='Y')                                   
      15 - filter("ROW_CURRENT_IND"='Y' AND ("NMI_STATUS_CD"='A' OR "NMI_STATUS_CD"='D'))                                   
      16 - access("NMI_SK"="NMI_SK")                                   
      17 - filter("ROW_CURRENT_IND"='Y')                                   
      18 - access("SERVICE_DELIVERY_POINT_SK"="SERVICE_DELIVERY_POINT_SK")                                   
      19 - access("SAP_INT_LOG_DEVICE_SK"="SAP_INT_LOG_DEVICE_SK")                                   
      20 - filter((SUBSTR("REGISTER_ID_CD",1,1)='4' OR SUBSTR("REGISTER_ID_CD",1,1)='5' OR                                    
                  SUBSTR("REGISTER_ID_CD",1,1)='6') AND "REGISTER_TYPE_CD"='C' AND "ROW_CURRENT_IND"='Y')                                   
      21 - filter("ROW_CURRENT_IND"='Y')                                   
      23 - access("SAP_INT_LOGICAL_REGISTER_SK"="SAP_INT_LOGICAL_REGISTER_SK")                                   
      24 - filter((SUBSTR("REGISTER_ID_CD",1,1)='1' OR SUBSTR("REGISTER_ID_CD",1,1)='2' OR                                    
                  SUBSTR("REGISTER_ID_CD",1,1)='3') AND "REGISTER_TYPE_CD"='C' AND "ROW_CURRENT_IND"='Y')                                   
      25 - filter("ROW_CURRENT_IND"='Y')Edited by: abhilash173 on Feb 24, 2013 9:16 PM
    Edited by: abhilash173 on Feb 24, 2013 9:18 PM

    Hi Paul,
    I misread your question initially .The system stats are outdated in both ( same result as seen from aux_stats) .I am not a DBA and do not have access to gather system stats fresh.
    select * from sys.aux_stats$
    SNAME     PNAME     PVAL1     PVAL2
    SYSSTATS_INFO     STATUS     NULL     COMPLETED
    SYSSTATS_INFO     DSTART     NULL     02-16-2011 15:24
    SYSSTATS_INFO     DSTOP     NULL     02-16-2011 15:24
    SYSSTATS_INFO     FLAGS     1     NULL
    SYSSTATS_MAIN     CPUSPEEDNW     1321.20523     NULL
    SYSSTATS_MAIN     IOSEEKTIM     10     NULL
    SYSSTATS_MAIN     IOTFRSPEED     4096     NULL
    SYSSTATS_MAIN     SREADTIM     NULL     NULL
    SYSSTATS_MAIN     MREADTIM     NULL     NULL
    SYSSTATS_MAIN     CPUSPEED     NULL     NULL
    SYSSTATS_MAIN     MBRC     NULL     NULL
    SYSSTATS_MAIN     MAXTHR     NULL     NULL
    SYSSTATS_MAIN     SLAVETHR     NULL     NULL

  • CBO not picking the right execution plan

    Database: Oracle 9.2.0.6 EE
    OS:Solaris 9
    I am trying to tune a query that is generated via Siebel Analytics. I am seeing a behaviour which is puzzling me but hopefully would be 'elementary' for someone like JPL.
    The query is based on a total of 7 tables. If I comment out any 2 dimension tables, the query picks up the right index on the fact table. However, the moment I add another table to the query, the plan goes awry.
    The query with 5 tables is as below:
    select count(distinct decode( T30256.HEADER_FLG , 'N' , T30256.ROW_WID ) ) as c1,
    T352305.DAY_DT as c2,
    case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  as c3,
    T352305.ROW_WID as c5
    from
                   W_PRODUCT_D T30955,
                   W_PRDATTRNM_D T44643,                         
                   W_DAY_D T352305,                 
                   W_ORDERITEM_F T30256,              
                   W_PRDATTR_D T40081                         
    where  ( T30955.ROW_WID = T44643.ROW_WID
    and T30256.LAST_UPD_DT_WID = T352305.ROW_WID
    and T30256.PROD_ATTRIB_WID = T40081.ROW_WID 
    and T30256.PROD_WID = T30955.ROW_WID
    and T30955.PROD_NAME = 'Mobile Subscription'
    and (case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  in ('BT150BB-18M', 'BT250BB-18M', 'BT50BB-18M', 'BT600BB-18M'))
    and T352305.DAY_DT between TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 7 and TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 1
    group by
    T352305.ROW_WID, T352305.DAY_DT,
    case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end
    ;And the execution plan is as below:
    | Id  | Operation                        |  Name                | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                 |                      |   269 | 25824 | 18660   (3)|
    |   1 |  SORT GROUP BY                   |                      |   269 | 25824 | 18660   (3)|
    |   2 |   NESTED LOOPS                   |                      |   269 | 25824 | 18658   (3)|
    |   3 |    NESTED LOOPS                  |                      |  6826 |   579K|  4734   (3)|
    |   4 |     MERGE JOIN CARTESIAN         |                      |     8 |   544 |     6  (17)|
    |   5 |      NESTED LOOPS                |                      |     1 |    54 |     4  (25)|
    |   6 |       TABLE ACCESS BY INDEX ROWID| W_PRODUCT_D          |     1 |    37 |     3  (34)|
    |*  7 |        INDEX RANGE SCAN          | W_PRODUCT_D_M2       |     1 |       |     2  (50)|
    |   8 |       TABLE ACCESS BY INDEX ROWID| W_PRDATTRNM_D        |     1 |    17 |     2  (50)|
    |*  9 |        INDEX UNIQUE SCAN         | W_PRDATTRNM_D_P1     |     1 |       |            |
    |  10 |      BUFFER SORT                 |                      |     8 |   112 |     4   (0)|
    |  11 |       TABLE ACCESS BY INDEX ROWID| W_DAY_D              |     8 |   112 |     3  (34)|
    |* 12 |        INDEX RANGE SCAN          | W_DAY_D_M39          |     8 |       |     2  (50)|
    |  13 |     TABLE ACCESS BY INDEX ROWID  | W_ORDERITEM_F        |   849 | 16131 |   592   (3)|
    |* 14 |      INDEX RANGE SCAN            | W_ORDERITEM_F_INDX9  |   852 |       |     4  (25)|
    |* 15 |    INDEX RANGE SCAN              | W_PRDATTR_D_M29_T1   |     1 |     9 |     3  (34)|
    ----------------------------------------------------------------------------------------------Note how the dimension tables W_PRODUCT_D & W_DAY_D are joined using cartesian join before joining to the fact table W_ORDERITEM_F using the composite index 'W_ORDERITEM_F_INDX9'. This index consists of LAST_UPD_DT_WID, PROD_WID and ACTION_TYPE_WID, which are foreign keys to the dimension tables.
    Now if I add one more table to the query:
    select count(distinct decode( T30256.HEADER_FLG , 'N' , T30256.ROW_WID ) ) as c1,
                  T352305.DAY_DT as c2,
                   case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  as c3,
                   T30371.X_BT_DLR_GROUP as c4,
                   T352305.ROW_WID as c5
              from                W_PRODUCT_D T30955,
                   W_PRDATTRNM_D T44643,                         
                   W_DAY_D T352305,                 
                   W_ORDERITEM_F T30256,              
                   W_ORDER_D T30371,                                            
                   W_PRDATTR_D T40081                         
              where  ( T30955.ROW_WID = T44643.ROW_WID
              and T30256.LAST_UPD_DT_WID = T352305.ROW_WID
              and T30256.PROD_ATTRIB_WID = T40081.ROW_WID
              and T30256.PROD_WID = T30955.ROW_WID
              and T30256.ORDER_WID = T30371.ROW_WID
              and T30955.PROD_NAME = 'Mobile Subscription'
              and T30371.STATUS_CD = 'Complete'
              and T30371.ORDER_TYPE = 'Sales Order' 
              and (case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end  in ('BT150BB-18M', 'BT250BB-18M', 'BT50BB-18M', 'BT600BB-18M'))
              and T352305.DAY_DT between TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 7 and TO_DATE('2008-09-27' , 'YYYY-MM-DD') - 1
              group by T30371.X_BT_DLR_GROUP, T352305.ROW_WID, T352305.DAY_DT,
              case  when T44643.PRODUCT_CLASS_NAME = 'MobileSubscription' then T40081.ATTR15_CHAR_VAL else 'Unspecified' end;I have added a single table W_ORDER_D to the query, and the execution plan is:
    | Id  | Operation                          |  Name               | Rows  | Bytes | Cost (%CPU)|
    |   0 | SELECT STATEMENT                   |                     |    44 |  6336 | 78695   (3)|
    |   1 |  SORT GROUP BY                     |                     |    44 |  6336 | 78695   (3)|
    |   2 |   NESTED LOOPS                     |                     |    44 |  6336 | 78694   (3)|
    |   3 |    NESTED LOOPS                    |                     |   269 | 27707 | 78145   (3)|
    |*  4 |     HASH JOIN                      |                     |  6826 |   626K| 64221   (3)|
    |   5 |      TABLE ACCESS BY INDEX ROWID   | W_DAY_D             |     8 |   112 |     4  (25)|
    |*  6 |       INDEX RANGE SCAN             | W_DAY_D_M39         |     1 |       |     3  (34)|
    |   7 |      TABLE ACCESS BY INDEX ROWID   | W_ORDERITEM_F       | 86886 |  2206K| 64197   (3)|
    |   8 |       NESTED LOOPS                 |                     | 87004 |  6797K| 64200   (3)|
    |   9 |        NESTED LOOPS                |                     |     1 |    54 |     4  (25)|
    |  10 |         TABLE ACCESS BY INDEX ROWID| W_PRODUCT_D         |     1 |    37 |     3  (34)|
    |* 11 |          INDEX RANGE SCAN          | W_PRODUCT_D_M2      |     1 |       |     2  (50)|
    |  12 |         TABLE ACCESS BY INDEX ROWID| W_PRDATTRNM_D       |     1 |    17 |     2  (50)|
    |* 13 |          INDEX UNIQUE SCAN         | W_PRDATTRNM_D_P1    |     1 |       |            |
    |* 14 |        INDEX RANGE SCAN            | W_ORDERITEM_F_N6    | 86886 |       |   212  (18)|
    |* 15 |     INDEX RANGE SCAN               | W_PRDATTR_D_M29_T1  |     1 |     9 |     3  (34)|
    |* 16 |    INDEX RANGE SCAN                | W_ORDER_D_N6        |     1 |    41 |     3  (34)|
    -----------------------------------------------------------------------------------------------Now CBO doesn't choose the composite index and the cost also has increased to 78695. But if I simply add an /*+ORDERED*/ hint to the above query, so that it should join the dimension tables before joining to fact table, then the cost drops to 20913. This means that CBO is not choosing the plan with the lowest cost. I tried increasing the optimizer_max_permutations to 80000, setting session level optimizer_dynamic_sampling to 8 (just to see if it works), but no success.
    Could you please advise how to overcome this problem?
    Many thanks.

    joshic wrote:
    Database: Oracle 9.2.0.6 EE
    OS:Solaris 9
    I am trying to tune a query that is generated via Siebel Analytics. I am seeing a behaviour which is puzzling me but hopefully would be 'elementary' for someone like JPL.
    The query is based on a total of 7 tables. If I comment out any 2 dimension tables, the query picks up the right index on the fact table. However, the moment I add another table to the query, the plan goes awry.
    I have added a single table W_ORDER_D to the query, and the execution plan is:
    Now CBO doesn't choose the composite index and the cost also has increased to 78695. But if I simply add an /*+ORDERED*/ hint to the above query, so that it should join the dimension tables before joining to fact table, then the cost drops to 20913. This means that CBO is not choosing the plan with the lowest cost. I tried increasing the optimizer_max_permutations to 80000, setting session level optimizer_dynamic_sampling to 8 (just to see if it works), but no success.Back to the original question:
    * Can you force the index usage of the composite index on W_ORDERITEM_F in the second query using an INDEX hint (instead of the ORDERED hint)? If yes, what does the plan look like, particularly what cost is reported?
    * Could you post the plans including the "Predicate Information" section below the plan output?
    * What is the definition of the index W_ORDERITEM_F_N6 on W_ORDERITEM_F?
    * Are the cardinalities reported in the execution plans close to reality or way off? The best way to verify this would be to run your query with SQL tracing enabled and generate a tkprof output. If you do so please post the tkprof output here as well.
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Understanding CBO decisions, explain plan instability

    Hi,
    I have a situation where the explain plan for a SELECT statement changes
    and performance takes a turn for the worse. The statement in question
    executes well and has the desired explain plan but after an insertion
    having a new eventtype ID the explain plan changes (doing lots of IO)
    and remains bad until the SGA is flushed.
    I would really like to know how to figure out how the CBO makes its
    decisions and why it changes its mind over a 2min period. Any pointers
    to get me started would be greatly appreciated.
    Table has columns C_ID, R_ID, EVENTTYPE, ...
    Regular indexes on (R_ID,C_ID) and EVENTTYPE.
    The SELECT runs well as long as the compound index is used first
    and runs poorly once a new EVENTTYPE is introduced (there are
    approx 10 event types and a new one is being introduced) and its
    index consulted first.
    Thansk,
    Darren

    Delayed block cleanout really confused me. I don't see how
    the details of block updates, SCNs and what is on disk relates
    to explain plans and a SQL statement that changes from
    performing well using the intended index to poorly using an index
    on a column having low cardinality.
    The SQL is actually quite trivial and a merely a lookup on this
    single table.
    SELECT * FROM table
    WHERE c_id = :1 and r_id = :2 and eventtype = :3
    Most of the time Oracle uses the intended index (r_id, c_id) and
    performs well. As long as both columns are used in the condition
    I don't think that ordering of them is an issue.
    If the CBO uses stats which get updated nightly after sufficient
    changes to the table then how can a statement change its execution
    plans (for the same user) following a addition of a row having a
    new EVENTTYPE value over a 2min period.
    That is the reason that I want to see/understand what the CBO
    is doing.
    It turns out that adding a new index (C_ID, R_ID, EVENTTYPE) was
    the bandaid needed to fix the problem but I'd like to get rid of
    it if its not needed.
    I'll look at these posts and try to get the differing plans back.
    At this point I'll need to drop the new index and break the app
    again and might receive some resistance to that.
    Thanks for your input,
    Darren

  • Is there a way to stop a query just after the cursor/plan is produced by CBO?

    Following suggestions of Kerry Osborne’s Oracle Blog » Blog Archive » Explain Plan Lies – Kerry Osborn…
    on the lies of "Explain plan" (and of "set autotrace on"  too) I'd like to try to stop a query/DML before actually it starts, just after the plan was produced and sql_id assigned.
    Is there any CLEAN way (other than trying CTRL-C) to do that?
    Thanks
    Paolo

    Hi
    PaolFili wrote:
    Thanks rp.
    I think my question is a little dofferent, but your reply give me an idea.(which has clear disadvantages , but can do the work).
    The problem is obtain in Lybrary Cache a plan,a SLQ_ID,PLAN_HASH for a query ( i.e. a 10days running query) that I cannot start-up.
    So my (suggested from your reply) idea is:
    1) to LOCK EXCLUSIVE (a table level) , **if it's possible** every table accessed in the query ( Yes, it can be really expansive in some production environment, but sometimes can be necessary ..)
      using :  LOCK TABLE table IN EXCLUSIVE MODE
    for each table accessed from query
    2) Startup the query that will be suspended form the lock on tables accessed + kill the sid,serial#,@Inst_id for the query.
    3) UNLOCK tables from EXCLUSIVE using "ROLLBACK"  in the session where LOCK TABLE.... was send.(to remake  tables to work for other queries)
    Any other ideas?
    Thanks
    Paolo
    you're planning on using locks to stop a query and you think in order to do so you need exclusive locks  on every table accessed in the query? And you are prepared to do that on a production system?
    And all of this is needed to troubleshoot a query that was running for 10 days -- i.e. a query that was available for all kinds of diagnostics during 10 days?
    Sorry, I think it wasn't a good idea for you to read that Osborne's blog post -- you should've started with more basic things. Way more basic.
    Best regards,
      Nikolay

  • Two different plans in TEST & Prod

    hi,
    we have a problem in production database where we find some sql statements running very slow.
    but if you run same SQL statement in TEST it runs < 2 secs.
    Production DB Prod.SchemaA  is exported into TEST DB as Test.SchemaA
    When study the explain plan, we find Prod explain plan is different than test. if you create sql profile, by copying TEST explain plan, it would run faster in Production.
    Now our question is why optimizer goes through two different plans when the schema structure same and data almost same in two databases?
    Note that, we have two almost identical schema's in Production. Prod.SchemaA and Prod.SchemaB has same object names but some Prod.SchemaB may have small difference in indexes/constraints.
    Users would run same SQL statement both in Prod.SchemaA & Prod.SchemaB time to time.
    thanks
    neal

    You can have a clear picture about the accuracy of your statistics by getting the execution plan from memory into the TEST and PROD environment. You can proceed as follows
    PROD> alter session set statistics_level=ALL;
    PROD> execute your query;
    PROD> select * from table (dbms_xplan.display_cursor(null,null, 'ALLSTATS LAST'));
    TEST> alter session set statistics_level=ALL;
    TEST> execute your query
    TEST> select * from table (dbms_xplan.display_cursor(null,null, 'ALLSTATS LAST'));
    This will give an execution plan showing the estimations(E-Rows) done by the CBO and the Actual (A-Rows) rows generated allowing you to judge the accuracy of your statistics.
    The predicate part of the execution plan can also show inportant information.
    Best regards
    Mohamed Houri
    www.hourim.wordpress.com

  • Execution plan with bind variable

    dear all
    I join two tables and get "index fast full scan" with high cost using bind variable
    but when I remove the bind variable it executes with "index" and with lower cost
    What is the reason and how should I know which execution plan is really used in real life?
    thanks
    john

    1) What is oracle version?
    2) Post here both query and their explain plan.
    In fact INDEX FAST FULL SCAN indicate is multiblock read for composite indexes(and based on your query and predicates).In this case CBO behavior as FULL TABLE SCAN(affected by db_multiblock_read_count,system stats,etc).And you use bind variable.So in bind variable case CBO define selectivity based on arithmetic(5% of the cardinality) ,if you use concrete values instead of bind variable CBO identify other selectivity based on statistics,histograms,.... then it was identify cost of multiblock read and single block reads.You can see these 10053 event.Finally it choose lower cost`s plan.

  • Any known CBO issues in 9.2.0.8?

    Hi, we have a job that runs considerably slower on 9.2.0.8 than it does on 9.2.0.5 and 10G R2. For many SQL statements it chooses a different execution plan than in the other versions and almost always a much slower one.
    Are there any known issues with the CBO in 9.2.0.8.?
    Rene

    Known does not mean known to Oracle at the time of release. It is a reference to the knowledge contained in the minds of people reading this forum. I'm asking for similar experiences with the 9.2.0.8 CBO (in that it acts different from the 9.2.0.5 CBO) and what to do with it.
    Rene

  • CBO bug? Lack of SORT UNIQUE.

    Hi all,
    Let's consider following case:
    create table tmp as select rownum id, 0 sign from dual connect by level <= 100;
    create index tmp_i on tmp(id,sign);
    create table t as
    select mod(rownum,2) id, mod(rownum,3) val
    from dual
    connect by level <= 100000;
    begin
       dbms_stats.gather_table_stats (
          user,
          'T',
          estimate_percent   => null,
          method_opt         => 'FOR ALL COLUMNS SIZE SKEWONLY',
          cascade            => true
    end;
    begin
       dbms_stats.gather_table_stats (
          user,
          'TMP',
          estimate_percent   => null,
          method_opt         => 'FOR ALL COLUMNS SIZE SKEWONLY',
          cascade            => true
    end;
    /As you can see it scans TMP_I 50 000 times for statement with max (irrespective of distinct in subquery).
    Is there any way to enforce CBO to make SORT UNIQUE for max as well as for count so that it scans TMP_I only 3 times?
    SQL> select --+ leading(t) use_nl(t tmp)
      2  max(id)
      3  from tmp tmp
      4  where tmp.sign = 0
      5  and tmp.id in (select val from t where id = 1);
       MAX(ID)
             2
    | Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   0 | SELECT STATEMENT    |       |      1 |        |      1 |00:00:00.14 |     159 |
    |   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.14 |     159 |
    |   2 |   NESTED LOOPS      |       |      1 |  49750 |  33333 |00:00:00.13 |     159 |
    |*  3 |    TABLE ACCESS FULL| T     |      1 |  50000 |  50000 |00:00:00.02 |     156 |
    |*  4 |    INDEX RANGE SCAN | TMP_I |  50000 |      1 |  33333 |00:00:00.07 |       3 |
    Predicate Information (identified by operation id):
       3 - filter("ID"=1)
       4 - access("TMP"."ID"="VAL" AND "TMP"."SIGN"=0)
    SQL> select --+ leading(t) use_nl(t tmp)
      2  max(id)
      3  from tmp tmp
      4  where tmp.sign = 0
      5  and tmp.id in (select distinct val from t where id = 1);
       MAX(ID)
             2
    | Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
    |   0 | SELECT STATEMENT    |       |      1 |        |      1 |00:00:00.14 |     159 |
    |   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.14 |     159 |
    |   2 |   NESTED LOOPS      |       |      1 |  49750 |  33333 |00:00:00.13 |     159 |
    |*  3 |    TABLE ACCESS FULL| T     |      1 |  50000 |  50000 |00:00:00.01 |     156 |
    |*  4 |    INDEX RANGE SCAN | TMP_I |  50000 |      1 |  33333 |00:00:00.07 |       3 |
    Predicate Information (identified by operation id):
       3 - filter("ID"=1)
       4 - access("TMP"."ID"="VAL" AND "TMP"."SIGN"=0)
    SQL> select --+ leading(t) use_nl(t tmp)
      2  count(id)
      3  from tmp tmp
      4  where tmp.sign = 0
      5  and tmp.id in (select val from t where id = 1);
    COUNT(ID)
             2
    | Id  | Operation            | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    |   0 | SELECT STATEMENT     |       |      1 |        |      1 |00:00:00.03 |     158 |       |       |          |
    |   1 |  SORT AGGREGATE      |       |      1 |      1 |      1 |00:00:00.03 |     158 |       |       |          |
    |   2 |   NESTED LOOPS       |       |      1 |      3 |      2 |00:00:00.03 |     158 |       |       |          |
    |   3 |    SORT UNIQUE       |       |      1 |  50000 |      3 |00:00:00.03 |     156 |  2048 |  2048 | 2048  (0)|
    |*  4 |     TABLE ACCESS FULL| T     |      1 |  50000 |  50000 |00:00:00.01 |     156 |       |       |          |
    |*  5 |    INDEX RANGE SCAN  | TMP_I |      3 |      1 |      2 |00:00:00.01 |       2 |       |       |          |
    Predicate Information (identified by operation id):
       4 - filter("ID"=1)
       5 - access("TMP"."ID"="VAL" AND "TMP"."SIGN"=0)I can't figure out why SORT UNIQUE is absent for statement with max.
    PS. 11gR2

    Thanks for reply.
    user503699 wrote:
    I don't think it is a good idea to compare your last and first query timings as they are 2 different queries.Ok. I could compare query with max(id), sign(count(*)+1) vs max(id), sign(1). They always produce the same results so can be considered as the same.
    But I think that max(id), count(*) vs max(id) was enough to explain my point.
    user503699 wrote:
    If you are so sure of that you can write something like following :
    SQL> with data as (select /*+ materialize */ distinct val as val from t where id = 1)
    select max(id) from tmp tmp where tmp.sign = 0 and tmp.id in (select val from data) ;  2 
    I thought about that. I’m reluctant to use undocumented hints such as materialize. So folowing query has almost the best plan for my data:
    with data as (select distinct val as val from t where id = 1 and rownum > 0)
    select
    max(id)
    from tmp tmp
    where tmp.sign = 0
    and tmp.id in (select * from data);
    | Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                    
    |   0 | SELECT STATEMENT        |       |     1 |     8 |    50   (8)| 00:00:01 |                                                                    
    |   1 |  SORT AGGREGATE         |       |     1 |     8 |            |          |                                                                    
    |   2 |   NESTED LOOPS          |       |     3 |    24 |    50   (8)| 00:00:01 |                                                                    
    |   3 |    VIEW                 |       |     3 |     9 |    50   (8)| 00:00:01 |                                                                    
    |   4 |     HASH UNIQUE         |       |     3 |    18 |    50   (8)| 00:00:01 |                                                                    
    |   5 |      COUNT              |       |       |       |            |          |                                                                    
    |*  6 |       FILTER            |       |       |       |            |          |                                                                    
    |*  7 |        TABLE ACCESS FULL| T     | 50000 |   292K|    47   (3)| 00:00:01 |                                                                    
    |*  8 |    INDEX RANGE SCAN     | TMP_I |     1 |     5 |     0   (0)| 00:00:01 |                                                                    
    Predicate Information (identified by operation id):                                                                                                  
       6 - filter(ROWNUM>0)                                                                                                                              
       7 - filter("ID"=1)                                                                                                                                
       8 - access("TMP"."ID"="DATA"."VAL" AND "TMP"."SIGN"=0)   And changing two hidden parameters may lead to the same plan as I expect:
    alter session set "_gby_hash_aggregation_enabled" = false;
    alter session set "_simple_view_merging" = false;
    with data as (select distinct val as val from t where id = 1)
    select
    max(id)
    from tmp tmp
    where tmp.sign = 0
    and tmp.id in (select * from data);
    | Id  | Operation             | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                      
    |   0 | SELECT STATEMENT      |       |     1 |    18 |    50   (8)| 00:00:01 |                                                                      
    |   1 |  SORT AGGREGATE       |       |     1 |    18 |            |          |                                                                      
    |   2 |   NESTED LOOPS        |       |     3 |    54 |    50   (8)| 00:00:01 |                                                                      
    |   3 |    VIEW               |       |     3 |    39 |    50   (8)| 00:00:01 |                                                                      
    |   4 |     SORT UNIQUE       |       |     3 |    18 |    50   (8)| 00:00:01 |                                                                      
    |*  5 |      TABLE ACCESS FULL| T     | 50000 |   292K|    47   (3)| 00:00:01 |                                                                      
    |*  6 |    INDEX RANGE SCAN   | TMP_I |     1 |     5 |     0   (0)| 00:00:01 |                                                                      
    Predicate Information (identified by operation id):                                                                                                  
       5 - filter("ID"=1)                                                                                                                                
       6 - access("TMP"."ID"="DATA"."VAL" AND "TMP"."SIGN"=0)   But here I've got two additional questions:
    1. no_use_hash_aggregation can be used instead of "alter session set "_gby_hash_aggregation_enabled" = false;"
    What hint can be used instead of "alter session set "_simple_view_merging" = false;"?
    2. Is there any way to enforce CBO to use for this one
    select
    max(id)
    from tmp tmp
    where tmp.sign = 0
    and tmp.id in (select distinct val as val from t where id = 1 and rownum > 0);
    | Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                
    |   0 | SELECT STATEMENT            |       |     1 |     5 |     3   (0)| 00:00:01 |                                                                
    |   1 |  SORT AGGREGATE             |       |     1 |     5 |            |          |                                                                
    |   2 |   FIRST ROW                 |       |     1 |     5 |     1   (0)| 00:00:01 |                                                                
    |*  3 |    INDEX FULL SCAN (MIN/MAX)| TMP_I |     1 |     5 |     1   (0)| 00:00:01 |                                                                
    |*  4 |     FILTER                  |       |       |       |            |          |                                                                
    |   5 |      COUNT                  |       |       |       |            |          |                                                                
    |*  6 |       FILTER                |       |       |       |            |          |                                                                
    |*  7 |        TABLE ACCESS FULL    | T     |     2 |    12 |     2   (0)| 00:00:01 |                                                                
    -------------------------------------------------------------------------------------  the same plan as for this
    with data as (select distinct val as val from t where id = 1 and rownum > 0)
    select
    max(id)
    from tmp tmp
    where tmp.sign = 0
    and tmp.id in (select * from data);
    | Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     |                                                                    
    |   0 | SELECT STATEMENT        |       |     1 |     8 |    50   (8)| 00:00:01 |                                                                    
    |   1 |  SORT AGGREGATE         |       |     1 |     8 |            |          |                                                                    
    |   2 |   NESTED LOOPS          |       |     3 |    24 |    50   (8)| 00:00:01 |                                                                    
    |   3 |    VIEW                 |       |     3 |     9 |    50   (8)| 00:00:01 |                                                                    
    |   4 |     HASH UNIQUE         |       |     3 |    18 |    50   (8)| 00:00:01 |                                                                    
    |   5 |      COUNT              |       |       |       |            |          |                                                                    
    |*  6 |       FILTER            |       |       |       |            |          |                                                                    
    |*  7 |        TABLE ACCESS FULL| T     | 50000 |   292K|    47   (3)| 00:00:01 |                                                                    
    |*  8 |    INDEX RANGE SCAN     | TMP_I |     1 |     5 |     0   (0)| 00:00:01 |                                                                    
    I don't have anything against subquery factoring clause. Just for personal interest.
    (I have read topic "Thread: Materialize a Subquery without using "with" clause"
    Materialize a Subquery without using "with" clause
    user503699 wrote:
    If you are not going to change other things (like stats collection method, table/index structures etc.) which allow optimizer to choose better plan and you know your data better, you may need to be very specific with the hints and also may have to use additional hints in order to influence optimizer decisions.
    One way to do that would be to get the base details from oracle as follows (and tweak them) :I didn't find keyword "ADVANCED" in specification for DISPLAY_CURSOR Function in documentation. Nice trick.
    But anyway outline data makes sense only in case when query already has desirable execution plan.

  • Subquery conditional execution using cbo

    hellou
    how i do for execute a subquery conditionally, using the cbo??
    i got an example:
    create table table1 AS
    SELECT * FROM (
        SELECT 1 id, 'a' boss FROM dual
       union all
        SELECT 3 id, 'b' boss FROM dual
       union all
        SELECT 5 id, 'a' boss FROM dual
       union all
        SELECT 7 id, 'b' boss FROM dual
       union all
        SELECT 9 id, 'a' boss FROM dual
    create index idx_table1 on table1(boss, id)
    create table table2 AS
    SELECT * FROM (
        SELECT 2 id, 'b' boss FROM dual
       union all
        SELECT 4 id, 'a' boss FROM dual
       union all
        SELECT 6 id, 'b' boss FROM dual
       union all
        SELECT 8 id, 'a' boss FROM dual
       union all
        SELECT 10 id, 'b' boss FROM dual
    create index idx_table2 on table2(boss, id)
    CREATE OR REPLACE FUNCTION print_hi
        isb in varchar2
    return number
    IS
    BEGIN
        dbms_output.put_Line(isb);
        return 0;
    END;
    -- the query !!!!!!!
    with data AS
        SELECT
        FROM (
            -- subquery #1
            SELECT
                1 query_name,
                id pibot,
                boss
            FROM table1
            WHERE print_hi(id) = 0
           union all
            -- subquery #2
            SELECT
                2 query_name,
                id pibot,
                boss
            FROM table2
    SELECT
        pibot + query_name / 10 pibot
    FROM data
    WHERE 1 = 1
        AND boss = :boss
        AND (
            query_name = :q
            AND pibot > :p
           OR query_name > :q )
        AND rownum <= 3i want than only the query #2 be executed.
    the query #1 print data in the screen when is executed (for the function print_hi).
    now i execute the query with the variables data as:
    boss = 'a'
    q = 2
    p = 0
    when i execute the query using rules, then not print anything in the screen.
    when i execute the query using costs, then print 1 5 9 in the screen. this means than the query #1 is being executed when this should not
    help .. tx
    SELECT * FROM v$version
    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - Prod
    PL/SQL Release 10.2.0.5.0 - Production
    CORE10.2.0.5.0Production
    TNS for Linux: Version 10.2.0.5.0 - Production
    NLSRTL Version 10.2.0.5.0 - Production

    As often is, the predicates section of the execution plan is quite revealing on this one.
    Take your original query
    explain plan for
    with data AS
    (SELECT *
    FROM (-- subquery #1
           SELECT 1 query_name,id pibot,boss
           FROM table1
           WHERE print_hi(id) = 0
           union all
            -- subquery #2
           SELECT 2 query_name,id pibot,boss
            FROM table2))
    SELECT pibot + query_name / 10 pibot
    FROM   data
    WHERE  1 = 1
    AND    boss = :boss
    AND   (query_name = :q
    AND    pibot > :p
    OR     query_name > :q )
    AND    rownum <= 3;
    select * from table(dbms_xplan.display);gives
    | Id  | Operation           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT    |            |     2 |    38 |     2   (0)| 00:00:01 |
    |*  1 |  COUNT STOPKEY      |            |       |       |            |          |
    |   2 |   VIEW              |            |     2 |    38 |     2   (0)| 00:00:01 |
    |   3 |    UNION-ALL        |            |       |       |            |          |
    |*  4 |     INDEX RANGE SCAN| IDX_TABLE1 |     1 |    16 |     1   (0)| 00:00:01 |
    |*  5 |     INDEX RANGE SCAN| IDX_TABLE2 |     1 |    16 |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter(ROWNUM<=3)
       4 - access("BOSS"=:BOSS)
           filter("PRINT_HI"(TO_CHAR("ID"))=0 AND (1>TO_NUMBER(:Q) OR
                  1=TO_NUMBER(:Q) AND "ID">TO_NUMBER(:P)))
       5 - access("BOSS"=:BOSS)
           filter(2>TO_NUMBER(:Q) OR 2=TO_NUMBER(:Q) AND "ID">TO_NUMBER(:P))Assuming that the FILTER logic in STEP 4 is followed to order, it's not then possible with this query as is to short-circuit the evaluation of PRINT_HI as it is evaluated first.
    When you make a change (just to q not necessarily to boss as well)
    from
    query_name = :qto
    query_name = 2You'll hopefully notice the difference in predicate evaluation with the extra filter step:
    | Id  | Operation             | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |            |     2 |    38 |     2   (0)| 00:00:01 |
    |*  1 |  COUNT STOPKEY        |            |       |       |            |          |
    |   2 |   VIEW                |            |     2 |    38 |     2   (0)| 00:00:01 |
    |   3 |    VIEW               |            |     2 |    38 |     2   (0)| 00:00:01 |
    |   4 |     UNION-ALL         |            |       |       |            |          |
    |*  5 |      FILTER           |            |       |       |            |          |
    |*  6 |       INDEX RANGE SCAN| IDX_TABLE1 |     1 |    16 |     1   (0)| 00:00:01 |
    |*  7 |      INDEX RANGE SCAN | IDX_TABLE2 |     1 |    16 |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter(ROWNUM<=3)
       5 - filter(1>TO_NUMBER(:Q))
       6 - access("BOSS"=:BOSS)
           filter("PRINT_HI"(TO_CHAR("ID"))=0)
       7 - access("BOSS"=:BOSS)
           filter("ID">TO_NUMBER(:P) OR 2>TO_NUMBER(:Q))

  • Using explain plan

    Hi,
    I am quite new to use explain plan in oracle.
    I want to know what are the important factors that we should emphasize to optimize a SQL query.
    Thanks in Advance,
    Dilip

    If I had to identify key SQL tuning factors to look for in relation to an explain plan I would say that number one is to verify that the plan is driving on the right tables in the proper order.
    Second looking at the SQL make sure it is not written in such a manner as to disable the use of available indexes such as when a trunc is done on an indexed date column so it can be compared equal to another date when a >= date value of midnight and < midnight of first day not desired could be used instead enabling use of the index on the date column by the optimizer. Implicit conversions of join column data types can also disable use of an index.
    Third, if the CBO is doing something other than what you expected do not just assume it is wrong. Try to figure out why it is doing what it is doing and then try to determine if it is right or wrong. I have caught people trying to tune SQL because they knew the plan was wrong, but did not actually test it before spending a lot of time to develop a different path that ran slower than the optimzer plan.
    HTH -- Mark D Powell --

  • Query rewrite by CBO

    Hello,
    Some days back, I came across a blog entry in which author concluded that when a = b and b = c, oracle does not conclude as a = c. He also provided a test case to prove his point. The URL is [http://sandeepredkar.blogspot.com/2009/09/query-performance-join-conditions.html]
    Now, I thought that that can not be true. So I executed his test case (on 10.2.04) and the outcome indeed proved his point. Initially, I thought it might be due to absense of PK-FK relationship. But even after adding the PK-FK relationship, there was no change in the outcome. Although, when I modified the subquery with list of values, both the queries performed equally. I tried asking the author on his blog but it seems he has not yet seen my comment.
    I am pasting his test case below. Can somebody please help me understand why CBO does not/can not use optimal plan here?
    SQL> create table cu_all (custid number, addr varchar2(200), ph number, cano number, acctype varchar2(10));
    Table created.
    SQL> create table ca_receipt (custid number, caamt number, cadt date, totbal number);
    Table created.
    SQL>
    SQL> insert into cu_all
      2  select     lvl,
      3          dbms_random.string('A',30),
      4          round(dbms_random.value(1,100000)),
      5          round(dbms_random.value(1,10000)),
      6          dbms_random.string('A',10)
      7  from       (select level "LVL" from dual connect by level <=200000);
    200000 rows created.
    SQL> insert into ca_receipt
      2  select     round(dbms_random.value(1,10000)),
      3          round(dbms_random.value(1,100000)),
      4          sysdate - round(dbms_random.value(1,100000)),
      5          round(dbms_random.value(1,100000))
      6  from       (select level "LVL" from dual connect by level <=500000);
    500000 rows created.
    SQL> create unique index pk_cu_all_ind on cu_all(custid);
    Index created.
    SQL> create index ind2_cu_all on cu_all(CANO);
    Index created.
    SQL> create index ind_ca_receipt_custid on ca_receipt(custid);
    Index created.
    SQL> exec dbms_stats.gather_table_stats(user,'CU_ALL', cascade=>true);
    PL/SQL procedure successfully completed.
    SQL> exec dbms_stats.gather_table_stats(user,'CA_RECEIPT', cascade=>true);
    PL/SQL procedure successfully completed.
    Now let us execute the query with trace on. This is the similar query which was provided to me.
    SQL> set autot trace
    SQL> SELECT     ca.*, cu.*
      2  FROM ca_receipt CA,
      3       cu_all CU
      4  WHERE       CA.CUSTID = CU.CUSTID
      5  AND         CA.CUSTID IN (SELECT CUSTID FROM cu_all START WITH custid = 2353
      6                CONNECT BY PRIOR CUSTID = CANO)
      7  ORDER BY ACCTYPE DESC;
    289 rows selected.
    Execution Plan
    Plan hash value: 3186098611
    | Id  | Operation                           | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                    |                       |  1000 | 81000 |   504   (2)| 00:00:07 |
    |   1 |  SORT ORDER BY                      |                       |  1000 | 81000 |   504   (2)| 00:00:07 |
    |*  2 |   HASH JOIN                         |                       |  1000 | 81000 |   503   (2)| 00:00:07 |
    |   3 |    NESTED LOOPS                     |                       |       |       |            |          |
    |   4 |     NESTED LOOPS                    |                       |  1000 | 26000 |   112   (1)| 00:00:02 |
    |   5 |      VIEW                           | VW_NSO_1              |    20 |   100 |    21   (0)| 00:00:01 |
    |   6 |       HASH UNIQUE                   |                       |    20 |   180 |            |          |
    |*  7 |        CONNECT BY WITH FILTERING    |                       |       |       |            |          |
    |   8 |         TABLE ACCESS BY INDEX ROWID | CU_ALL                |     1 |     9 |     2   (0)| 00:00:01 |
    |*  9 |          INDEX UNIQUE SCAN          | PK_CU_ALL_IND         |     1 |       |     1   (0)| 00:00:01 |
    |  10 |         NESTED LOOPS                |                       |       |       |            |          |
    |  11 |          CONNECT BY PUMP            |                       |       |       |            |          |
    |  12 |          TABLE ACCESS BY INDEX ROWID| CU_ALL                |    20 |   180 |    21   (0)| 00:00:01 |
    |* 13 |           INDEX RANGE SCAN          | IND2_CU_ALL           |    20 |       |     1   (0)| 00:00:01 |
    |* 14 |      INDEX RANGE SCAN               | IND_CA_RECEIPT_CUSTID |    50 |       |     2   (0)| 00:00:01 |
    |  15 |     TABLE ACCESS BY INDEX ROWID     | CA_RECEIPT            |    50 |  1050 |    52   (0)| 00:00:01 |
    |  16 |    TABLE ACCESS FULL                | CU_ALL                |   200K|    10M|   389   (1)| 00:00:05 |
    Predicate Information (identified by operation id):
       2 - access("CA"."CUSTID"="CU"."CUSTID")
       7 - access("CANO"=PRIOR "CUSTID")
       9 - access("CUSTID"=2353)
      13 - access("CANO"=PRIOR "CUSTID")
      14 - access("CA"."CUSTID"="CUSTID")
    Statistics
              1  recursive calls
              0  db block gets
           2249  consistent gets
             25  physical reads
              0  redo size
          11748  bytes sent via SQL*Net to client
            729  bytes received via SQL*Net from client
             21  SQL*Net roundtrips to/from client
              7  sorts (memory)
              0  sorts (disk)
            289  rows processed
    If you look at the query, it seems to be normal one.
    But the problem is here-
    Query is having two tables CA and CU. From the inner CU table query, it fetches records and joins with CA table an CA table Joins with CU table using the same column.
    Here the inner query joins with CA table and cardinality of the query gets changed. So it is opting FTS when joining to CU table again.
    This is causing the performance bottleneck. So to resolve the issue, I have change the joining condition.
    Now if we check, following is the proper execution plan. Also the consistents gets have been reduced to 797 against 2249 in original query.
    SQL> SELECT     ca.*, cu.*
      2  FROM ca_receipt CA,
      3       cu_all CU
      4  WHERE       CA.CUSTID = CU.CUSTID
      5  AND         CU.CUSTID IN (SELECT CUSTID FROM cu_all START WITH custid = 2353
      6                CONNECT BY PRIOR CUSTID = CANO)
      7  ORDER BY ACCTYPE DESC;
    289 rows selected.
    Execution Plan
    Plan hash value: 3713271440
    | Id  | Operation                           | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                    |                       |  1000 | 81000 |   133   (2)| 00:00:02 |
    |   1 |  SORT ORDER BY                      |                       |  1000 | 81000 |   133   (2)| 00:00:02 |
    |   2 |   NESTED LOOPS                      |                       |       |       |            |          |
    |   3 |    NESTED LOOPS                     |                       |  1000 | 81000 |   132   (1)| 00:00:02 |
    |   4 |     NESTED LOOPS                    |                       |    20 |  1200 |    42   (3)| 00:00:01 |
    |   5 |      VIEW                           | VW_NSO_1              |    20 |   100 |    21   (0)| 00:00:01 |
    |   6 |       HASH UNIQUE                   |                       |    20 |   180 |            |          |
    |*  7 |        CONNECT BY WITH FILTERING    |                       |       |       |            |          |
    |   8 |         TABLE ACCESS BY INDEX ROWID | CU_ALL                |     1 |     9 |     2   (0)| 00:00:01 |
    |*  9 |          INDEX UNIQUE SCAN          | PK_CU_ALL_IND         |     1 |       |     1   (0)| 00:00:01 |
    |  10 |         NESTED LOOPS                |                       |       |       |            |          |
    |  11 |          CONNECT BY PUMP            |                       |       |       |            |          |
    |  12 |          TABLE ACCESS BY INDEX ROWID| CU_ALL                |    20 |   180 |    21   (0)| 00:00:01 |
    |* 13 |           INDEX RANGE SCAN          | IND2_CU_ALL           |    20 |       |     1   (0)| 00:00:01 |
    |  14 |      TABLE ACCESS BY INDEX ROWID    | CU_ALL                |     1 |    55 |     1   (0)| 00:00:01 |
    |* 15 |       INDEX UNIQUE SCAN             | PK_CU_ALL_IND         |     1 |       |     0   (0)| 00:00:01 |
    |* 16 |     INDEX RANGE SCAN                | IND_CA_RECEIPT_CUSTID |    50 |       |     2   (0)| 00:00:01 |
    |  17 |    TABLE ACCESS BY INDEX ROWID      | CA_RECEIPT            |    50 |  1050 |    52   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       7 - access("CANO"=PRIOR "CUSTID")
       9 - access("CUSTID"=2353)
      13 - access("CANO"=PRIOR "CUSTID")
      15 - access("CU"."CUSTID"="CUSTID")
      16 - access("CA"."CUSTID"="CU"."CUSTID")
    Statistics
              1  recursive calls
              0  db block gets
            797  consistent gets
              1  physical reads
              0  redo size
          11748  bytes sent via SQL*Net to client
            729  bytes received via SQL*Net from client
             21  SQL*Net roundtrips to/from client
              7  sorts (memory)
              0  sorts (disk)
            289  rows processed

    user503699 wrote:
    Hello,
    Some days back, I came across a blog entry in which author concluded that when a = b and b = c, oracle does not conclude as a = c. He also provided a test case to prove his point. The URL is [http://sandeepredkar.blogspot.com/2009/09/query-performance-join-conditions.html]
    Now, I thought that that can not be true. So I executed his test case (on 10.2.04) and the outcome indeed proved his point. Initially, I thought it might be due to absense of PK-FK relationship. But even after adding the PK-FK relationship, there was no change in the outcome. Although, when I modified the subquery with list of values, both the queries performed equally. I tried asking the author on his blog but it seems he has not yet seen my comment.I see that Jonathan provided a helpful reply to you while I was in the process of setting up a test case.
    Is it possible that the optimizer is correct? What if... the optimizer transformed the SQL statement? What if... the original SQL statement actually executes faster than the modified SQL statement? What if... the autotrace plans do not match the plans shown on that web page?
    The first execution with the original SQL statement:
    ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'test_case';
    SET AUTOTRACE TRACE
    SELECT     ca.*, cu.*
    FROM ca_receipt CA,
         cu_all CU
    WHERE       CA.CUSTID = CU.CUSTID
    AND         CA.CUSTID IN (SELECT CUSTID FROM cu_all START WITH custid = 2353
                  CONNECT BY PRIOR CUSTID = CANO)
    ORDER BY ACCTYPE DESC;
    Execution Plan
    Plan hash value: 2794552689
    | Id  | Operation                          | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                   |                       |  1001 | 81081 |  1125   (2)| 00:00:01 |
    |   1 |  SORT ORDER BY                     |                       |  1001 | 81081 |  1125   (2)| 00:00:01 |
    |   2 |   NESTED LOOPS                     |                       |  1001 | 81081 |  1123   (1)| 00:00:01 |
    |   3 |    NESTED LOOPS                    |                       |  1001 | 26026 |   114   (2)| 00:00:01 |
    |   4 |     VIEW                           | VW_NSO_1              |    20 |   100 |    22   (0)| 00:00:01 |
    |   5 |      HASH UNIQUE                   |                       |    20 |   180 |            |          |
    |*  6 |       CONNECT BY WITH FILTERING    |                       |       |       |            |          |
    |   7 |        TABLE ACCESS BY INDEX ROWID | CU_ALL                |     1 |    19 |     2   (0)| 00:00:01 |
    |*  8 |         INDEX UNIQUE SCAN          | PK_CU_ALL_IND         |     1 |       |     1   (0)| 00:00:01 |
    |   9 |        NESTED LOOPS                |                       |       |       |            |          |
    |  10 |         CONNECT BY PUMP            |                       |       |       |            |          |
    |  11 |         TABLE ACCESS BY INDEX ROWID| CU_ALL                |    20 |   180 |    22   (0)| 00:00:01 |
    |* 12 |          INDEX RANGE SCAN          | IND2_CU_ALL           |    20 |       |     1   (0)| 00:00:01 |
    |  13 |     TABLE ACCESS BY INDEX ROWID    | CA_RECEIPT            |    50 |  1050 |    52   (0)| 00:00:01 |
    |* 14 |      INDEX RANGE SCAN              | IND_CA_RECEIPT_CUSTID |    50 |       |     2   (0)| 00:00:01 |
    |  15 |    TABLE ACCESS BY INDEX ROWID     | CU_ALL                |     1 |    55 |     1   (0)| 00:00:01 |
    |* 16 |     INDEX UNIQUE SCAN              | PK_CU_ALL_IND         |     1 |       |     0   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       6 - access("CANO"=PRIOR "CUSTID")
       8 - access("CUSTID"=2353)
      12 - access("CANO"=PRIOR "CUSTID")
      14 - access("CA"."CUSTID"="$nso_col_1")
      16 - access("CA"."CUSTID"="CU"."CUSTID")
    Statistics
              1  recursive calls
              0  db block gets
            232  consistent gets
              7  physical reads
              0  redo size
           2302  bytes sent via SQL*Net to client
            379  bytes received via SQL*Net from client
              5  SQL*Net roundtrips to/from client
              5  sorts (memory)
              0  sorts (disk)
             52  rows processedThe second SQL statement which was modified:
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'test_case2';
    SELECT     ca.*, cu.*
    FROM ca_receipt CA,
         cu_all CU
    WHERE       CA.CUSTID = CU.CUSTID
    AND         CU.CUSTID IN (SELECT CUSTID FROM cu_all START WITH custid = 2353
                  CONNECT BY PRIOR CUSTID = CANO)
    ORDER BY ACCTYPE DESC;
    Execution Plan
    Plan hash value: 497148844
    | Id  | Operation                           | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                    |                       |  1001 | 81081 |   136   (3)| 00:00:01 |
    |   1 |  SORT ORDER BY                      |                       |  1001 | 81081 |   136   (3)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID       | CA_RECEIPT            |    50 |  1050 |    52   (0)| 00:00:01 |
    |   3 |    NESTED LOOPS                     |                       |  1001 | 81081 |   134   (2)| 00:00:01 |
    |   4 |     NESTED LOOPS                    |                       |    20 |  1200 |    43   (3)| 00:00:01 |
    |   5 |      VIEW                           | VW_NSO_1              |    20 |   100 |    22   (0)| 00:00:01 |
    |   6 |       HASH UNIQUE                   |                       |    20 |   180 |            |          |
    |*  7 |        CONNECT BY WITH FILTERING    |                       |       |       |            |          |
    |   8 |         TABLE ACCESS BY INDEX ROWID | CU_ALL                |     1 |    19 |     2   (0)| 00:00:01 |
    |*  9 |          INDEX UNIQUE SCAN          | PK_CU_ALL_IND         |     1 |       |     1   (0)| 00:00:01 |
    |  10 |         NESTED LOOPS                |                       |       |       |            |          |
    |  11 |          CONNECT BY PUMP            |                       |       |       |            |          |
    |  12 |          TABLE ACCESS BY INDEX ROWID| CU_ALL                |    20 |   180 |    22   (0)| 00:00:01 |
    |* 13 |           INDEX RANGE SCAN          | IND2_CU_ALL           |    20 |       |     1   (0)| 00:00:01 |
    |  14 |      TABLE ACCESS BY INDEX ROWID    | CU_ALL                |     1 |    55 |     1   (0)| 00:00:01 |
    |* 15 |       INDEX UNIQUE SCAN             | PK_CU_ALL_IND         |     1 |       |     0   (0)| 00:00:01 |
    |* 16 |     INDEX RANGE SCAN                | IND_CA_RECEIPT_CUSTID |    50 |    |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       7 - access("CANO"=PRIOR "CUSTID")
       9 - access("CUSTID"=2353)
      13 - access("CANO"=PRIOR "CUSTID")
      15 - access("CU"."CUSTID"="$nso_col_1")
      16 - access("CA"."CUSTID"="CU"."CUSTID")
    Statistics
              1  recursive calls
              0  db block gets
            162  consistent gets
              0  physical reads
              0  redo size
           2302  bytes sent via SQL*Net to client
            379  bytes received via SQL*Net from client
              5  SQL*Net roundtrips to/from client
              5  sorts (memory)
              0  sorts (disk)
             52  rows processed
    ALTER SESSION SET EVENTS '10053 trace name context off';The question might be asked, does the final SQL statement actually executed look the same as the original? Slightly reformatted:
    The first SQL statement:
    SELECT
      CA.*,
      CU.*
    FROM
      CA_RECEIPT CA,
      CU_ALL CU
    WHERE
      CA.CUSTID = CU.CUSTID
      AND CA.CUSTID IN (
        SELECT
          CUSTID
        FROM
          CU_ALL
        START WITH
          CUSTID = 2353
        CONNECT BY PRIOR
          CUSTID = CANO)
    ORDER BY
      ACCTYPE DESC;
    Final Transformation:
    SELECT
      "CA"."CUSTID" "CUSTID",
      "CA"."CAAMT" "CAAMT",
      "CA"."CADT" "CADT",
      "CA"."TOTBAL" "TOTBAL",
      "CU"."CUSTID" "CUSTID",
      "CU"."ADDR" "ADDR",
      "CU"."PH" "PH",
      "CU"."CANO" "CANO",
      "CU"."ACCTYPE" "ACCTYPE"
    FROM
      (SELECT DISTINCT
        "CU_ALL"."CUSTID" "$nso_col_1"
      FROM
        "TESTUSER"."CU_ALL" "CU_ALL"
      WHERE
        "CU_ALL"."CANO"=PRIOR "CU_ALL"."CUSTID"
      CONNECT BY
        "CU_ALL"."CANO"=PRIOR "CU_ALL"."CUSTID") "VW_NSO_1",
      "TESTUSER"."CA_RECEIPT" "CA",
      "TESTUSER"."CU_ALL" "CU"
    WHERE
      "CA"."CUSTID"="VW_NSO_1"."$nso_col_1"
      AND "CA"."CUSTID"="CU"."CUSTID"
    ORDER BY
      "CU"."ACCTYPE" DESC;The second SQL statement:
    SELECT
      CA.*,
      CU.*
    FROM
      CA_RECEIPT CA,
      CU_ALL CU
    WHERE
      CA.CUSTID = CU.CUSTID
      AND CU.CUSTID IN (
        SELECT
          CUSTID
        FROM
          CU_ALL
        START WITH
          CUSTID = 2353
        CONNECT BY PRIOR
          CUSTID = CANO)
    ORDER BY
      ACCTYPE DESC;
    Final Transformation:
    SELECT
      "CA"."CUSTID" "CUSTID",
      "CA"."CAAMT" "CAAMT",
      "CA"."CADT" "CADT",
      "CA"."TOTBAL" "TOTBAL",
      "CU"."CUSTID" "CUSTID",
      "CU"."ADDR" "ADDR",
      "CU"."PH" "PH",
      "CU"."CANO" "CANO",
      "CU"."ACCTYPE" "ACCTYPE"
    FROM
      (SELECT DISTINCT
        "CU_ALL"."CUSTID" "$nso_col_1"
      FROM
        "TESTUSER"."CU_ALL" "CU_ALL"
      WHERE
        "CU_ALL"."CANO"=PRIOR "CU_ALL"."CUSTID"
      CONNECT BY
        "CU_ALL"."CANO"=PRIOR "CU_ALL"."CUSTID") "VW_NSO_1",
      "TESTUSER"."CA_RECEIPT" "CA",
      "TESTUSER"."CU_ALL" "CU"
    WHERE
      "CA"."CUSTID"="CU"."CUSTID"
      AND "CU"."CUSTID"="VW_NSO_1"."$nso_col_1"
    ORDER BY
      "CU"."ACCTYPE" DESC;Now, let's take a look at performance, flushing the buffer cache to force physical reads:
    SET AUTOTRACE OFF
    SET TIMING ON
    SET AUTOTRACE TRACEONLY STATISTICS
    SET ARRAYSIZE 100
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    SELECT
      CA.*,
      CU.*
    FROM
      CA_RECEIPT CA,
      CU_ALL CU
    WHERE
      CA.CUSTID = CU.CUSTID
      AND CA.CUSTID IN (
        SELECT
          CUSTID
        FROM
          CU_ALL
        START WITH
          CUSTID = 2353
        CONNECT BY PRIOR
          CUSTID = CANO)
    ORDER BY
      ACCTYPE DESC;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    SELECT
      CA.*,
      CU.*
    FROM
      CA_RECEIPT CA,
      CU_ALL CU
    WHERE
      CA.CUSTID = CU.CUSTID
      AND CU.CUSTID IN (
        SELECT
          CUSTID
        FROM
          CU_ALL
        START WITH
          CUSTID = 2353
        CONNECT BY PRIOR
          CUSTID = CANO)
    ORDER BY
      ACCTYPE DESC;The output:
    /* (with AND CA.CUSTID IN...) */
    52 rows selected.
    Elapsed: 00:00:00.64
    Statistics
              0  recursive calls
              0  db block gets
            232  consistent gets
            592  physical reads
              0  redo size
           2044  bytes sent via SQL*Net to client
            346  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              5  sorts (memory)
              0  sorts (disk)
             52  rows processed
    /* (with AND CU.CUSTID IN...) */
    52 rows selected.
    Elapsed: 00:00:00.70
    Statistics
              0  recursive calls
              0  db block gets
            162  consistent gets
            712  physical reads
              0  redo size
           2044  bytes sent via SQL*Net to client
            346  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              5  sorts (memory)
              0  sorts (disk)
             52  rows processedThe original SQL statement completed in 0.64 seconds, and the second completed in 0.70 seconds.
    Charles Hooper
    IT Manager/Oracle DBA
    K&M Machine-Fabricating, Inc.

  • CBO not picking correct indexes or doing Full Scans

    Database version - 10.2.0.4
    OS : Solaris 5.8
    Storage: SAN
    Application : PeopleSoft Financials
    DB size : 450 gb
    DB server : 12 CPU ( 900 Mghz each ), 36 GB RAM
    ASMM - sga_target_size = 5 gb
    Locally managed tablespaces - MANUAL
    - db_file_multiblock_read_count - not set explicitly in spfile ( implicitly defaulted to 128 )
    - other optimizer related parameters are set to default
    - system_statistics - CPUSPEEDNW=456.282722513089, IOSEEKTIM =10, IOTFRSPEED=4096     
    - dictionary object system stats were last gather in Nov 09
    - stats on schema objs are gathered every night using custom script, but I have to say there are some histograms on some tables which were gathered by PS admins
    begin
    dbms_stats.gather_schema_stats(
    ownname=> 'SCHEMANM' ,
    cascade=> DBMS_STATS.AUTO_CASCADE,
    estimate_percent=> DBMS_STATS.AUTO_SAMPLE_SIZE,
    degree=> 10,
    no_invalidate=> DBMS_STATS.AUTO_INVALIDATE,
    granularity=> 'AUTO',
    method_opt=> 'FOR ALL COLUMNS SIZE 1',
    options=> 'GATHER STALE');
    end;
    Details :
    We are experiencing erratic database performance. It was upgraded from 9i to 10g along with PS software upgrade. A job that runs on one day in 12 hrs(that is high in itself) would take more than 24 hrs another day.
    We have Test and Staging envs on other servers which do not have performance issues of production magnitude. The test, staging dbs are clones of prod, created by ftp'ing files from one location to another, not sure if that makes any difference but just pointing out.
    On Prod db some symptoms which baffle me are :
    1) sql executing for over 40 minutes, check the plan and it is using an "incorrect" index, idx1. Hint sql with "correct" index, idx2, and it runs in few seconds. result set <400 rows. Cost with hint with idx2 is HIGHER. This scenario is still understandable as CBO is likely to pick a lower cost.
    - But why is there so much discrepancy in cost and response time?
    - what is influencing the CBO to pick an index which is obviously not the fastest response time?
    2) sql plan shows FTS , execution time , runs forever . But a hint with index in this case shows the cost is LOWER and response time is in seconds, so why is CBO not even evaluating this index path? Because as I understand the CBO, it will always pick the lower cost plan.
    What is influencing the CBO. Is it system stats? or any other database parameter? or the hardware ? the large SGA?? histogram ?? Stats gathering?? is there is any known issue with DBMS_STATS.AUTO_SAMPLE_SIZE and cardinaility?
    Where should I put my focus?
    What am I looking for ?
    I do have Jonathan Lewis's Cost-Based Oracle Fundamentals which I have just started so perhaps I will be enlightened but while I read it, it would be of immense help to get some advice from forum gurus.
    At this time I am not posting any exec plan or code, but I can do so if required.
    Thanks,
    JC

    Picking up just a couple of points - the ones about: why can performance change so much from one day to the next, and how can the optimizer miss a plan which (when hinted) shows a lower cost.
    NOTE: These are only suggestions that may allow you to look at critical code and recognise the pattern of behaviour
    Performance change:
    You are using "gather stale" which means tables won't get new statistics is the volume of change since the last collection is "small". But peoplesoft tables can be big, so some tables may need a lot of data to change (which might take several days or weeks) before they get new stats. The 10g optimizer is able to compare the high-values stored with the predicate values supplied in queries, and decide that since the predicate is higher than the known highest value, it should scale down its estimates of data returned. After a few days when the stats haven't changed, the optimizer suddenly gets to the point where the estimated data size is much too small and the plan changes to something that you can see is bad. The typical example here is a date column that increases with time, and a query on "recent data" - the optimizer basically says: "you want 9th Feb - the high value says 28th Jan, there's virtually no data". Keeping date and sequence-based high-values up to date is important. (See dbms_stats.set_column_stats).
    Lower cost plans available:
    Sometimes this is a bug. Sometimes it's an unlucky side effect. When a query has a large number of tables in a single query block, the optimizer can only examine a limited subset of the possible join orders (for example, a 10-table join has over 3million join orders, and the default limit is 2,000 checked). Because of this limit, Oracle starts working through a few joins orders in a methodical manner, then does a "big jump" to a different set of join orders where it checks a few more join orders, then does another "big jump". It may be that it never gets to your nice plan with the lower cost because it doesn't have time. However, by putting in the hint, you may make some of the orders the optimizer would have examined drop out of the "methodical list" - so it examines a few more in one sequence, or possibly "jumps" to a different sequence that it would not othewise have reached. (I wrote a related blog item some time ago that might make this clearer, even though it's not about exactly the same phenomenon: http://jonathanlewis.wordpress.com/2006/11/03/table-order/ ).
    Your recent comment about dynamic sampling is correct, by the way - by default (which for your version is is level 2 as a system parameter) it will only apply for tables which don't have any statistics. It's only for higher levels, or when explicitly hinted for tables, that it can apply to tables with existing statistics.
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    http://www.jlcomp.demon.co.uk
    "Science is more than a body of knowledge; it is a way of thinking"
    Carl Sagan
    To post code, statspack/AWR report, execution plans or trace files, start and end the section with the tag {noformat}{noformat} (lowercase, curly brackets, no spaces) so that the text appears in fixed format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

Maybe you are looking for

  • Payment procedure

    Hi experts actually i am ABAP guy .. i am going through Purchasing business scenario functiopnally , now learned from PO creation to Invoice my doubt is how can i proceed to make the payment againist the created invoice. i have cretaed  purchsing -po

  • Need to reinstall Photoshop to the same imac

    My imac received a new hard drive and photoshop has to be reinstalled.  I need to make sure that I am still able to install it to another computer later on.  I am able to use this on two computers and since this is the same computer, it needs to be c

  • Crm -isu integration , regulated scenarion

    hello all , we are in process of crm isu integration for regulated scenario . crm 2007 / ecc 6 isu  currently bp and BA are getting replicated . we are in process of replicating technical master data . however i need to know as we are in regulated ma

  • Question about operations allowed in methods of stateless and stateful bean

    Hello, Can anyone tell me why ejbRemove and ejbCreate are allowed entreprise beans and resource manager access in stateful session beans and not in stateless session beans? Thanks in advance, Julien Martin.

  • Multiple account assignment in service entry sheet (ML81N)

    Hi all, Is there any difference (other than the number of service entry sheet lines) if I create one service line in ML81N using the multiple account assignment screen with 2 different order numbers or 2 SES lines with single account assignment? Ther