Cbo problem

10053 report:
BASE STATISTICAL INFORMATION
Table Stats::
Table: TEMP Alias: TEMP
#Rows: 1000 #Blks: 3 AvgRowLen: 15.00
Table Stats::
Table: TEST_DEFAULT Alias: T
#Rows: 1156944 #Blks: 1891 AvgRowLen: 7.00
Index Stats::
Index: I_TEST_DEFAULT_1 Col#: 1
LVLS: 2 #LB: 2265 #DK: 1 LB/K: 2265.00 DB/K: 1889.00 CLUF: 1889.00
User hint to use this index
Access path analysis for TEMP
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for TEMP[TEMP]
Table: TEMP Alias: TEMP
Card: Original: 1000.000000 Rounded: 1000 Computed: 1000.00 Non Adjusted: 1000.00
Access Path: TableScan
Cost: 3.01 Resp: 3.01 Degree: 0
Cost_io: 3.00 Cost_cpu: 171364
Resp_io: 3.00 Resp_cpu: 171364
Best:: AccessPath: TableScan
Cost: 3.01 Degree: 1 Resp: 3.01 Card: 1000.00 Bytes: 0
Access path analysis for TEST_DEFAULT
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for TEST_DEFAULT[T]
Table: TEST_DEFAULT Alias: T
Card: Original: 1156944.000000 Rounded: 1 Computed: 0.50 Non Adjusted: 0.50
kkofmx: index filter:"T"."OBJECT_NAME"<>'~'
**Access Path: index (FullScan)**
**Index: I_TEST_DEFAULT_1**
**resc_io: 2268.00 resc_cpu: 247540396**
**ix_sel: 1.000000 ix_sel_with_filters: 0.000000**
****** Logdef predicate Adjustment *******
Final IO cst 0.00 , CPU cst 50.00
****** End Logdef Adjustment *******
Cost: 2283.12  Resp: 2283.12  Degree: 1
Best:: AccessPath: IndexRange
Index: I_TEST_DEFAULT_1
Cost: 2283.12 Degree: 1 Resp: 2283.12 Card: 0.50 Bytes: 0
OPTIMIZER STATISTICS AND COMPUTATIONS
GENERAL PLANS
Considering cardinality-based initial join order.
Permutations for Starting Table :0
Join order[1]: TEMP[TEMP]#0 TEST_DEFAULT[T]#1
Now joining: TEST_DEFAULT[T]#1
NL Join
Outer table: Card: 1000.00 Cost: 3.01 Resp: 3.01 Degree: 1 Bytes: 15
Access path analysis for TEST_DEFAULT
kkofmx: index filter:"T"."OBJECT_NAME"<>'~'
Access Path: index (AllEqJoinGuess)
Index: I_TEST_DEFAULT_1
resc_io: 2.00  resc_cpu: 15293
ix_sel: 1.000000  ix_sel_with_filters: 0.000000
****** Logdef predicate Adjustment *******
Final IO cst 0.00 , CPU cst 50.00
****** End Logdef Adjustment *******
NL Join : Cost: 4866.95  Resp: 4866.95  Degree: 1
Cost_io: 2003.00  Cost_cpu: 57862664244
Resp_io: 2003.00  Resp_cpu: 57862664244
Best NL cost: 4866.95
resc: 4866.95 resc_io: 2003.00 resc_cpu: 57862664244
resp: 4866.95 resp_io: 2003.00 resc_cpu: 57862664244
Join Card: 0.000000 = = outer (1000.000000) * inner (0.500000) * sel (0.000000)
Join Card - Rounded: 1 Computed: 0.00
Best:: JoinMethod: NestedLoop
Cost: 4866.95 Degree: 1 Resp: 4866.95 Card: 0.00 Bytes: 22
Best so far: Table#: 0 cost: 3.0085 card: 1000.0000 bytes: 15000
Table#: 1 cost: 4866.9474 card: 0.0000 bytes: 22
select /*+ use_nl(t) index(t) leading(temp) */ t.* from test_default t ,temp where
t.object_name=temp.pk and object_name<>'~'
============
Plan Table
============
| Id | Operation | Name | Rows | Bytes | Cost | Time |
| 0 | SELECT STATEMENT | | | | 4867 | |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 22 | 4867 | 00:00:59 |
| 3 | TABLE ACCESS FULL | TEMP | 1000 | 15K | 3 | 00:00:01 |
| 4 | INDEX RANGE SCAN | I_TEST_DEFAULT_1| 1 | | 5 | 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID | TEST_DEFAULT | 1 | 7 | 5 | 00:00:01 |
Predicate Information:
3 - filter("TEMP"."PK"<>'~')
4 - access("T"."OBJECT_NAME"="TEMP"."PK")
4 - filter("OBJECT_NAME"<>'~')
Content of other_xml column
===========================
db_version : 11.2.0.1
parse_schema : SYS
plan_hash : 1943699946
plan_hash_2 : 3291268812
Outline Data:
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
DB_VERSION('11.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
FULL(@"SEL$1" "TEMP"@"SEL$1")
INDEX(@"SEL$1" "T"@"SEL$1" ("TEST_DEFAULT"."OBJECT_NAME"))
LEADING(@"SEL$1" "TEMP"@"SEL$1" "T"@"SEL$1")
USE_NL(@"SEL$1" "T"@"SEL$1")
NLJ_BATCHING(@"SEL$1" "T"@"SEL$1")
END_OUTLINE_DATA
problem:
from the 10053 report,I found cbo has known the ix_sel_with_filters is 0.000000 ,why also use cost =5 for index range scan,I think it could use cost zero or one as cost.

jinyu wrote:
*NL Join : Cost: 4866.95  Resp: 4866.95  Degree: 1*
*Cost_io: 2003.00  Cost_cpu: 57862664244*
*Resp_io: 2003.00  Resp_cpu: 57862664244*
Best NL cost: 4866.95
resc: 4866.95  resc_io: 2003.00  resc_cpu: 57862664244
resp: 4866.95  resp_io: 2003.00  resc_cpu: 57862664244
You can see in these lines that Oracle has estimated the I/O cost of the index probe to be 2, with a total I/O cost of (1000 * 2 + 3). The 2 is the cost of the blevel descent. The anomaly is the very high CPU cost for doing the range scan. It seems likely that this is an optimizer bug, and somehow Oracle has brought in the CPU cost of scanning the entire index at this point, rather than the CPU cost of examining a couple of leaf blocks and branch blocks.
Regards
Jonathan Lewis

Similar Messages

  • Problem with xs:integer (I think)

    Hi,
    Firstly, I'm using Oracle database version 11.2.0.1.0
    The overall task is to absorb data from an XML file and create records in a single destination table.
    I've studied the excellent thread at Load xml data in Oracle table
    and copied and hacked Odie's examples.
    I've got something to work, but there's just that one final problem, explained so.
    To test out my code, I wrapped the "select" that gets the data from the XML file into a cursor For loop, and inside
    the loop body I just use dbms_output so I can see that the values are being processed okay. This works a treat, so my
    final task was to abandon the cursor For loop and instead make the select statement the source of data for an Insert
    statement. This is where my plans become unstuck.
    In order to cater for duplicate rows, I'm using the "at" bit of the "for" loop as so: "for $i at $bibnum in /collection/record".
    That bit of data (available through the variable "$bibnum") when printed out via the older dbms_output code did show
    a pleasing consecutive sequence of digits. But try and insert this into a plain database table and all I get is nulls. Yuk.
    Trying to read around this, I've managed through dubious means to glean that the variable is of type "xs:integer". It seems converting
    this to a oracle "number" type is problematic. There is mention on the web page http://docs.oracle.com/cd/E14571_01/doc.1111/e15867/app_xquery_sql_reference.htm
    about conversion from "number" to "xs:integer", hence I am presuming that the converse also holds.
    But the blooming thing still doesn't work.
    Other numbers from the select statement populate into my destination table fine. It's just the xs:integer that's the issue.
    I've tried changing the "columns" part of the xmltable call and used "number", "number(8)", "number(8,0)" and other variants. No joy.
    I've also tried changing the column type of the target table. Still no joy.
    I've tried converting the xs:integer to a xs:decimal, and then use that. Still nothing.
    Time to throw myself on the mercy of the forum. Any easy way to convert the xs:integer into a plain string?
    If there is no obvious answer, I will throw together a small self-contained piece of example code and come back here.
    Any help appreciated; thanks in advance.
    Mungo (newbie with xmltables - probably going round the "long" way on this task :-)

    That's a funny one, SELECT is working but INSERT is not...
    I guess it's an issue with the CBO and XQuery optimization.
    If you're always using a variable as your XML source, you can disable it by adding the NO_XML_QUERY_REWRITE hint. It should solve the problem :
    SQL> create table raw_bib (
      2    recordID    number
      3  , datafieldID number
      4  , tag         number
      5  , subfield    varchar2(10)
      6  , val         varchar2(4000)
      7  )
      8  ;
    Table created
    SQL> var xml_data varchar2(4000)
    SQL>
    SQL> begin
      2   :xml_data := '<collection>
      3   <record>
      4    <datafield tag="1">
      5     <subfield code="1d1s1">ABC</subfield>
      6     <subfield code="1d1s2">DEF</subfield>
      7     <subfield code="1d1s3">GHI</subfield>
      8    </datafield>
      9    <datafield tag="2">
    10     <subfield code="1d2s1">ABC</subfield>
    11     <subfield code="1d2s2">DEF</subfield>
    12     <subfield code="1d2s3">GHI</subfield>
    13    </datafield>
    14   </record>
    15   <record>
    16    <datafield tag="1">
    17     <subfield code="2d1s1">ABC</subfield>
    18     <subfield code="2d1s2">DEF</subfield>
    19     <subfield code="2d1s3">GHI</subfield>
    20    </datafield>
    21   </record>
    22  </collection>';
    23  end;
    24  /
    PL/SQL procedure successfully completed
    SQL>
    SQL> insert into raw_bib(recordID, datafieldID, tag, subfield, val)
      2  select /*+ no_xml_query_rewrite */
      3         recordID, datafieldID, tag, subfield, val
      4  from xmltable(
      5   'for $i at $bibnum in /collection/record
      6   return
      7   for $j at $dfnum in  $i/datafield
      8   return
      9   for $k in $j/subfield
    10     return element r {
    11      element finalData {data($k)}
    12      , element datafieldtag {data($j/@tag) }
    13      , element subfieldcode { data($k/@code) }
    14      , element whichdatafield {data($dfnum)}
    15      , element bibnumber { $bibnum }
    16      }
    17    '
    18  passing xmltype(:xml_data)
    19  columns recordID    number         path 'bibnumber'
    20        , datafieldID number         path 'whichdatafield'
    21        , tag         number         path 'datafieldtag'
    22        , subfield    varchar2(10)   path 'subfieldcode'
    23        , val         varchar2(4000) path 'finalData'
    24  )
    25  ;
    9 rows inserted
    SQL> select * from raw_bib;
      RECORDID DATAFIELDID        TAG SUBFIELD   VAL
             1           1          1 1d1s1      ABC
             1           1          1 1d1s2      DEF
             1           1          1 1d1s3      GHI
             1           2          2 1d2s1      ABC
             1           2          2 1d2s2      DEF
             1           2          2 1d2s3      GHI
             2           1          1 2d1s1      ABC
             2           1          1 2d1s2      DEF
             2           1          1 2d1s3      GHI
    9 rows selected

  • Problems with Late 2011 MBP (catalog corrupt, won't boot from USB/CD)

    Hello,
    I have had some problems with my Late 2011 MBP running OSX 10.8.x (latest update)
    I was using Safari when suddenly my screen froze. It has happened a couple of times before but it usually is either: 1.) a black screen for 5 seconds while nothing works responds and then it continues work like nothing happened, or 2.) just a freeze for a moment which goes away within a few seconds. I have visited the official service and they found nothing wrong with my laptop and said that it may have been just random occurrence. This time it froze and as I waited the fans went crazy and had no other option but to shut down from the power button. Later, when I wanted to boot up, it gets to the Apple logo, the circle spins and the small bar below appears and after a second or two, it disappears and then the computer shuts down. I went to recovery mode and used disk utility to verify and repair the problem (which only works to find out the problem, not to fix it, thanks anyway apple) Heres what it showed:
    Verifying volume “nihil”
    Checking file systemChecking Journaled HFS Plus volume.
    Checking extents overflow file.
    Checking catalog file.
    Keys out of order
    Invalid extent entry
    Incorrect size for file .mdworker_2013-07-21-081г41_эartin-RichaѲds-эacBѯok-ѐro.crash.plist
    (It should be 0 instead of 4398046511104)
    Illegal name
    Invalid extent entry
    Invalid extent entry
    Incorrect size for file .mdworker_2013-07-22-б20303_MartiѮ-RiѣharѤs-MѡcBoѯk-Pro.crash.plist
    (It should be 0 instead of 67108864)
    File has incorrect number of links (id = 60851670)
    (It should be 1 instead of 67108865)
    Invalid extent entry
    Invalid extent entry
    Incorrect block count for file .mdworker_2013-08-04-145002_Martin-Richards-MacBook-Pro.crash.plist
    (It should be 0 instead of 1024)
    Invalid extent entry
    Invalid extent entry
    Incorrect size for file .opendirectoryd_201г-08-04-б516а5_MѡrtiѮ-Riѣhards-MacBook-Pro.crash.plist
    (It should be 0 instead of 67108864)
    File has incorrect number of links (id = 66286495)
    (It should be 1 instead of 67108865)
    Invalid catalog record type
    The volume nihil could not be verified completely.
    Error: This disk needs to be repaired. Click Repair Disk.
    Verify and Repair volume “nihil”
    Checking file systemChecking Journaled HFS Plus volume.
    Checking extents overflow file.
    Checking catalog file.
    Keys out of order
    Invalid extent entry
    Incorrect size for file .mdworker_2013-07-21-081г41_эartin-RichaѲds-эacBѯok-ѐro.crash.plist
    (It should be 0 instead of 4398046511104)
    Illegal name
    Invalid extent entry
    Invalid extent entry
    Incorrect size for file .mdworker_2013-07-22-б20303_MartiѮ-RiѣharѤs-MѡcBoѯk-Pro.crash.plist
    (It should be 0 instead of 67108864)
    File has incorrect number of links (id = 60851670)
    (It should be 1 instead of 67108865)
    Invalid extent entry
    Invalid extent entry
    Incorrect block count for file .mdworker_2013-08-04-145002_Martin-Richards-MacBook-Pro.crash.plist
    (It should be 0 instead of 1024)
    Invalid extent entry
    Invalid extent entry
    Incorrect size for file .opendirectoryd_201г-08-04-б516а5_MѡrtiѮ-Riѣhards-MacBook-Pro.crash.plist
    (It should be 0 instead of 67108864)
    File has incorrect number of links (id = 66286495)
    (It should be 1 instead of 67108865)
    Invalid catalog record type
    The volume nihil could not be verified completely.
    Volume repair complete.Updating boot support partitions for the volume as required.Error: Disk Utility can’t repair this disk. Back up as many of your files as possible, reformat the disk, and restore your backed-up files.
    I tried to boot DiskWarrior from a USB and a CD, after pushing enter in the bootable device's screen, I get a continuous loop of 3 beeps and I can't boot from either of the mediums.
    I also tried the Single-user mode (Command-s when booting) and the /sbin/fsck -fy said that my HD is not completely verifiable. Also, 3/4 of the files mentioned in disk utility are also mentioned in this process, with errors as forrows: keys out of order, invalid index key, invalid extent entries (7 times), incorrect block counts, number of links and incorrect sizes for the foretold files and invalid catalog record type.
    The reason why I'm not doing a clean install is that the last few days I've been in the process of deleting unnecessary items on my laptop so I could make a back-up (as for some reason, Time Machine is awfully slow and a new 600 gb backup would take and enormous amount of time, but that's a problem for another day) and as I had not yet reached the backing up part, my data is locked on this (possibly) corrupt HD. How should I advance and what steps should I take?
    My first and most important mission would be to get back into my OS to make a back-up. Then I'd deal with the "not being able to boot form USB nor CD" and the TM problem.
    Thank you all in advance,
    Martin

    Before you even start, consider that there may be no Windows 7 driver support for some of the hardware in your laptop. You won't know which hardware devices and functions are unsupported until you find out the hard way. In some cases, a driver conflict could cripple your computer.
    Like most OEMS, Toshiba pre-installs Windows 8 to boot with EFI on a GPT hard drive. Your Windows 7 install disc, on the other hand, most likely boots with a BIOS from an MBR. Therefore, your Windows 7 disc will not boot your computer.
    You would need to start by performing a low-level format of your hard drive. This completely erases the disc and its metadata. Then you could boot from your Windows installation disc and try to install Windows 7. How successful you will be depends on driver support.
    All things considered, you should stay with Windows 8. Next time, more research before you buy.

  • SQL Area Usage, Performance Problem

    Hi,
    I'm a software engineer, not a DBA, with a lot of doubts about our production environment, but I think that I have found a problem at our production Database.
    At our development database when I execute the same SQL statement over than onces, I can see this behaviour (for example):
    * First execution 580 milisenconds.
    * Second execution 21 milisencons.
    As where I know, I understand that the compiled SQL statement is stored at the SQL Area, and by that reason the second execution is faster then the first one. Is that assumption correct?
    If it is correct, I have a problem on our production Database because it does not work as expected. I have done a lot of trials, and SQL statement executions do not reduce her time execution when I do consecutive SQL execution.
    Could you help me? I think that the parameter shared_pool_size value is too lower for our production server.
    Thanks in advance.
    Best Regards,
    Joan

    Just a comment about performance tuning and troubleshooting in general Joan.
    It is very dangerous to base your conclusions on observation only. Consider the following example:
    SQL> set timing on
    SQL> select count(*) from all_objects;
    COUNT(*)
    10296
    Elapsed: 00:00:18.38
    SQL>
    SQL> -- now using the magically warp speed hint
    SQL> select /*+ WARP_SPEED */ count(*) from all_objects;
    COUNT(*)
    10296
    Elapsed: 00:00:00.32
    SQL>
    From 18 seconds to less than half a second. It does look, based on pure observation of the results, that there is a WARP_SPEED hint in Oracle and it does increase performance dramatically. And we can also infer that this is an undocumented feature added by one of the Oracle kernel developers that is also a Star Trek fan. ;-)
    But if we turn on SQL tracing (as suggested), we will see that the first SELECT did a lot of physical I/O. The 2nd SELECT did the same work, but without having to do the very expensive physical I/O - as the data blocks it need to hit (again) was now in memory (inside Oracle's buffer cache).
    It had nothing to do with an invalid and non-existing CBO hint called WARP_SPEED.
    The critical bit is KNOWING exactly what you are measuring when using this type of approach. If you do not know that, you are in no position to determine a sound and valid conclusion.
    Side note on shared pool size - one of the worse mistakes can be to increase it. It can cause incredible damage to performance on an instance that deals with bindless/non-sharable SQL as the pool that Oracle needs to use to determine if a soft parse is possible gets to be huge.. without the benefit of being able to soft parse and forced to hard parse anyway. And that hard parse also now added to the size of the pool.

  • Problem in Customising JTable's Functionality

    Problem Scenario :
    We are facing a problem related to JTables. In our GUI, we have used JTables and the data model that we are using for the table is a bit complicated. Complicated in the sense that we want different values(multiple) in each cell of a particular column in the table and we want to use JComboBox at that particular cell. For achieving this we have set the values in the JComboBox in its renderer class. But to set the user selected value in the particular cell JComboBox we initialized a new JComboBox in the renderer class. With this the GUI is working fine but it has raised a problem that if we renderer the component another JComboBox appears in the same cell. The problem is obvious as we are initializing a new JComboBox in the renderer class, but to solve our purpose we don�t have another way.
    With the kind of data model we are using is it possible to create a JTable with combo boxes in a particular cell having different option values in each cell?
    Could someone suggest a solution for this problem?
    Regards
    Prajkta Bonde
    [email protected]

    I have done it around 4 years back. Add filled JComboBox as table data.
    Attached sample code should help
    // Imports
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    class SimpleTableExample
              extends      JFrame
         // Instance attributes used in this example
         private     JPanel          topPanel;
         private     JTable          table;
         private     JScrollPane scrollPane;
         // Constructor of main frame
         public SimpleTableExample()
              // Set the frame characteristics
              setTitle( "Simple Table Application" );
              setSize( 300, 200 );
              setBackground( Color.gray );
              // Create a panel to hold all other components
              topPanel = new JPanel();
              topPanel.setLayout( new BorderLayout() );
              getContentPane().add( topPanel );
              // Create columns names
              String columnNames[] = { "Column 1", "Column 2", "Column 3" };
              Object dataValues[][] = new Object[10][3];
              for(int row=0;row<dataValues.length;row++) {
                   for(int col=0;col<dataValues[row].length;col++){
                        JComboBox tempBox = new JComboBox();
                        for(int data=0;data<10;data++){
                             tempBox.addItem("Row "+row+" Column "+col+" Data "+data);
                        dataValues[row][col]=tempBox;
              // Create a new table instance
              table = new JTable( dataValues, columnNames );
            comboBoxColumn(table.getColumnModel().getColumn(0));
            comboBoxColumn(table.getColumnModel().getColumn(1));
            comboBoxColumn(table.getColumnModel().getColumn(2));
              // Add the table to a scrolling pane
              scrollPane = new JScrollPane( table );
              topPanel.add( scrollPane, BorderLayout.CENTER );
        public void comboBoxColumn(TableColumn comboBoxCol) {
            comboBoxCol.setCellEditor(new TableComponentEditor());
            comboBoxCol.setCellRenderer(new TableComponentRenderer());
            //Set up tool tip for the sport column header.
            TableCellRenderer headerRenderer = comboBoxCol.getHeaderRenderer();
            if (headerRenderer instanceof DefaultTableCellRenderer) {
                 ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Click the sport to see a list of service stations");
        } //end of method
        class TableComponentEditor extends DefaultCellEditor {
            * Constructor
            * @param none
            TableComponentEditor() {
                super(new JComboBox());
            * Called when table Cell is clicked
            * @param table
            * @param value - Object associated with the particular column for which it is called
            * @param isSelected -whether the particular cell is selected
            * @param row - The row to which cell belongs
            * @param column - The Column To which Cell Belongs
            public  Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                cbo = (JComboBox)value;
                return cbo;
            *  getCellEditorValue
            * @return Object
            public Object getCellEditorValue() {
                return cbo;
            /***************CLASS VARIABLES***********************/
            private JComboBox cbo = null;
        class TableComponentRenderer  implements TableCellRenderer {
            public  Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)  {
                return (JComboBox)value;
         // Main entry point for this example
         public static void main( String args[] )
              // Create an instance of the test application
              SimpleTableExample mainFrame     = new SimpleTableExample();
              mainFrame.setVisible( true );
    }

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

  • JSF Problem with events

    4 comboboxes need to be used in several JSF pages.
    This cbo are stored in the jspf file :
    <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
    <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
    <f:subview id="cboSearch">
        <p>
            <h:selectOneMenu id="cboSites" value="#{searchFormMB.siteChoisi}"
                              onchange="submit()" valueChangeListener="#{searchFormMB.eventCboSitesChanged}">
                <f:selectItems id="siteItem" value="#{searchFormMB.siteItems}"/>
            </h:selectOneMenu>
        </p>
        <p>
            <h:selectOneMenu id="cboPeriodes" value="#{searchFormMB.periodeChoisie}"
                             onchange="submit()" valueChangeListener="#{searchFormMB.eventCboPeriodesChanged}">
                <f:selectItems id="periodeItem" value="#{searchFormMB.periodeItems}"/>
            </h:selectOneMenu>
        </p>
        <p>
            <h:selectOneMenu id="cboPersonnels" value="#{searchFormMB.auteurChoisi}"
                             onchange="submit()" valueChangeListener="#{searchFormMB.eventCboPersonnelsChanged}">
                <f:selectItems id="personnelItem" value="#{searchFormMB.personnelItems}"/>
            </h:selectOneMenu>
        </p>
        <p>
            <h:selectOneMenu id="cboEssais" value="#{searchFormMB.essaiChoisi}" binding="#{searchFormMB.cboEssai}"
                             onchange="submit()" valueChangeListener="#{searchFormMB.eventCboEssaiChanged}">
                <f:selectItems id="essaiItem" value="#{searchFormMB.essaiItems}"/>
            </h:selectOneMenu>
        </p>
    </f:subview>The problem is with the last cbo (id="cboEssais") since "#{searchFormMB.eventCboEssaiChanged}" is called for the active page and for all previous pages. That means it is called once for the first page visited, twice for the second page visited, three time for the third page visited, ...
    Any idea about this problem ? Thanks

    When i change page valueChangeListener fired at stage RENDER_RESPONSE 6 and when cbo is change valueChangeListener fired at stage PROCESS_VALIDATIONS 3.
    In both cases the number of successive fires (call of valueChangeListener) is equal to the number of (re)visited pages since beginning of the session.

  • Why CBO don't use function-base index when I use like and bind variable

    Hello
    I have litle problem with function-base index and like with bind variable.
    When I use like with bind variable, the CBO don't use my function-base index.
    For example when I create table and index:
    ALTER SESSION SET NLS_SORT='BINARY_CI';
    ALTER SESSION SET NLS_COMP='LINGUISTIC';
    alter session set nls_language='ENGLISH';
    -- DROP TABLE TEST1;
    CREATE TABLE TEST1 (K1 VARCHAR2(32));
    create index test1_idx on test1(nlssort(K1,'nls_sort=BINARY_CI'));
    INSERT INTO TEST1
    SELECT OBJECT_NAME FROM ALL_OBJECTS;
    COMMIT;
    When I run:
    ALTER SESSION SET NLS_SORT='BINARY_CI';
    ALTER SESSION SET NLS_COMP='LINGUISTIC';
    SELECT * FROM TEST1 WHERE K1 = 'abcd';
    or
    SELECT * FROM TEST1 WHERE K1 LIKE 'abcd%';
    CBO use index.
    PLAN_TABLE_OUTPUT
    SQL_ID 4vrmp7cshbvqy, child number 1
    SELECT * FROM TEST1 WHERE K1 LIKE 'abcd%'
    Plan hash value: 1885706448
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | | | 1 (100)| |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST1 | 2 | 98 | 1 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | TEST1_IDX | 2 | | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - access("TEST1"."SYS_NC00002$">=HEXTORAW('6162636400') AND
    "TEST1"."SYS_NC00002$"<HEXTORAW('6162636500') )
    but when I run
    SELECT * FROM TEST1 WHERE K1 LIKE :1;
    CBO don't use index
    PLAN_TABLE_OUTPUT
    SQL_ID 9t461s1669gru, child number 0
    SELECT * FROM TEST1 WHERE K1 LIKE :1
    Plan hash value: 4122059633
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | | | 89 (100)| |
    |* 1 | TABLE ACCESS FULL| TEST1 | 2 | 48 | 89 (3)| 00:00:02 |
    Predicate Information (identified by operation id):
    1 - filter("K1" LIKE :1)
    What should I change to force CBO to use index.
    I don't wont use index hint in query.
    My oracle version:
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE     11.2.0.1.0     Production
    TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production

    OK. But why if I create normal index (create index test1_idx on test1(K1)) and return to default nls settings this same query use index.
    PLAN_TABLE_OUTPUT
    SQL_ID 9t461s1669gru, child number 0
    SELECT * FROM TEST1 WHERE K1 LIKE :1
    Plan hash value: 598212486
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | | | 1 (100)| |
    |* 1 | INDEX RANGE SCAN| TEST1_IDX | 1 | 18 | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    1 - access("K1" LIKE :1)
    filter("K1" LIKE :1)
    Note
    - dynamic sampling used for this statement (level=2)
    when index is function-base (create index test1_idx on test1(nlssort(K1,'nls_sort=BINARY_CI')))
    PLAN_TABLE_OUTPUT
    SQL_ID 9t461s1669gru, child number 1
    SELECT * FROM TEST1 WHERE K1 LIKE :1
    Plan hash value: 4122059633
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | | | 89 (100)| |
    |* 1 | TABLE ACCESS FULL| TEST1 | 3 | 54 | 89 (3)| 00:00:02 |
    Predicate Information (identified by operation id):
    1 - filter("K1" LIKE :1)
    Note
    - dynamic sampling used for this statement (level=2)
    when I create index with upper function "index test1_idx on test1(upper(K1))" the query use index
    SELECT * FROM TEST1 WHERE upper(K1) LIKE :1
    Plan hash value: 1885706448
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | | | 1 (100)| |
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST1 | 4481 | 157K| 1 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | TEST1_IDX | 806 | | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - access("TEST1"."SYS_NC00002$" LIKE :1)
    filter("TEST1"."SYS_NC00002$" LIKE :1)
    Note
    - dynamic sampling used for this statement (level=2)

  • RBO X CBO

    Hi everybody.
    I would like to understand where what we are missing here.
    We have several installations running 10g, and it's default value for OPTIMIZER_MODE is ALL_ROWS. Well, if there are no statistcs for the application tables, the RDBMS uses by default RULE BASED OPTIMIZER. Ok.
    After the statistics are generated (oracle job, automatic), the RDBMS turns to use COST BASED OPTIMIZER. I can understand that.
    The problem is: why do several queries run much slower when using CBO? When we analyze the execution plan, we see the wrong indexes being used.
    The solution I have for now is set OPTIMIZER_MODE=RULE. Then everything runs smoothly again.
    Why does this happen? Shouldn't CBO, after the statistics are generated, find out the best execution plan possible? I really can't use CBO on our sites, because performance is so much worse...
    Thanks in advance.
    Carlos Inglez

    Hi Carlos,
    The solution I have for now is set OPTIMIZER_MODE=RULE. Then everything runs smoothly again.It's almost always an issue with CBO parms or CBO statistics.
    There are several issues in 10g CBO, and here are my notes:
    http://www.dba-oracle.com/t_slow_performance_after_upgrade.htm
    Oracle has improved the cost-based Oracle optimizer in 9.0.5 and again in 10g, so you need to take a close look at your environmental parameter settings (init.ora parms) and your optimizer statistics.
    - Check optimizer parameters - Ensure that you are using the proper optimizer_mode (default is all_rows) and check optimal settings for optimizer_index_cost_adj (lower from the default of 100) and optimizer_index_caching (set to a higher value than the default).
    - Re-set optimizer costing - Consider unsetting your CPU-based optimizer costing (the 10g default, a change from 9i). CPU costing is best of you see CPU in your top-5 timed events in your STATSPACK/AWR report, and the 10g default of optimizercost_model=cpu will try to minimize CPU by invoking more full scans, especially in tablespaces with large blocksizes. To return to your 9i CBO I/O-based costing, set the hidden parameter "_optimizer_cost_model"=io
    - Verify deprecated parameters - you need to set optimizer_features_enable = 10.2.0.2 and optimizer_mode = FIRST_ROWS_n (or ALL_ROWS for a warehouse, but remove the 9i CHOOSE default).
    - Verify quality of CBO statistics - Oracle 10g does automatic statistics collection and your original customized dbms_stats job (with your customized parameters) will be overlaid. You may also see a statistics deficiency (i.e. not enough histograms) causing performance issues. Re-analyze object statistics using dbms_stats and make sure that you collect system statistics.
    Hope this helps. . .
    Donald K. Burleson
    Oracle Press author

  • Using to_date causes CBO to use wrong index

    I'm working on switching an application from using the Rule-based optimizer to use the Cost-based Optimizer on Oracle 9iR2. I'm having problems with the following query:
    select report_rsn, reports.facility_code,
           exams.facility_code
      from exams join reports using (report_rsn)
    where reports.transcribed_date
            between to_date('17-Mar-2005')
                and to_date('18-Mar-2005')
       and exams.dictated_for_rsn = 3323
       and exams.status IN ('S','T')There is an index on the reports.transcribed_date column and a compound index on (exams.dictated_for_rsn,exams.status).
    EXPLAIN PLAN tells me this query will use the transcribed_date as the driving index, but when I run the query through SQL_TRACE, tkprof says that it used the other index instead. That took a long time. (90 seconds)
    If I change the to_date() functions to be ANSI date literals (DATE '2005-03-17' and DATE '2005-03-18'), EXPLAIN PLAN says the same as before, and tkprof says that it actually used that plan. The query returned almost instantly.
    We have CURSOR_SHARING set to 'SIMILAR', and my best guess is that there is something involving the "bind parameter peeking" that is causing the problem. It appears as if the optimizer does not evaluate the to_date() function between "peeking" at the bind variable and determining the execution plan, so it does not know that the two dates are only a day apart. However, I haven't been able to find anything in the docs to confirm my suspicions.
    I've done a search for queries in our system that use the to_date() function as part of the where clause, and it doesn't look like a Herculean task to simply change them all, but I'm wondering two things:
    1) Is there a better way to solve the problem?
    2) Is there any information on this behavior out there that I can read to verify my suspicions? This might be the most important, because in order to finalize the switch to CBO, I need to be able to tell my supervisor that "this sort of thing" won't happen on our production box.
    -- Jeff Beal

    Jeff,
    Could you post your plan under both scenarios? WhatHere are the relevant* (different) portions of the execution plan (as given by TKPROF):
    * I actually ran TKProf against a much larger query, but the controlling part is the query that I included.
    When using DATE literal:
    Rows     Row Source Operation
          0               NESTED LOOPS 
          0                TABLE ACCESS BY INDEX ROWID REPORTS
          6                 INDEX RANGE SCAN IX_REPORTS_TRDATE (object id 109215)
          0                TABLE ACCESS BY INDEX ROWID EXAMS
          0                 INDEX RANGE SCAN IX_FK_EXAMS_11 (object id 96878)When using to_date function
    Rows     Row Source Operation
      46517                NESTED LOOPS 
      46517                 INLIST ITERATOR 
      46517                  TABLE ACCESS BY INDEX ROWID EXAMS
      46517                   INDEX RANGE SCAN IX_FK_EXAMS_4 (object id 139880)
          0                 TABLE ACCESS BY INDEX ROWID REPORTS
      46517                   INDEX UNIQUE SCAN PK_REPORTS (object id 109164)
    are the indexes on the tables and on what columns are
    they present?'ix_fk_exams_4' is a compound index on the exams table.  The first column is 'dictated_for_rsn' and the second is 'status'.  'pk_reports' is an index on reports.report_rsn - the primary key of the table.  'ix_reports_trdate' is on the reports.transcribed_date column.  'ix_fk_exams_11' is on exams.report_rsn (the foreign key to the reports table).
    Just to give you an idea on size, the exams table has about six million rows; the reports table has about 5.5 million.  I would categorize the transcribed_date column as evenly distributed, along with the values in dictated_for_rsn.  The status column is heavily skewed, with 'T' and 'S' being the two most common statuses.

  • RBO vs CBO : Are you going to maintain RBO in DBMS?

    Hello, Oracle?
    I'm facing many critics about the type of SQL optimization from customer.
    I'm still using RBO in application SQL because, sometimes, your automatic optimization (analyze) make the execution plan of performance-oriented SQL worse and that kind of SQL have to be executed very long time.
    So I checked these SQLs and appended the hint ("/*+ RULE */").
    From that time, these SQLs were always executed in the same execution plan
    and other performance issues were disappeared.
    I want to ask you that
    1) Did I do wrong things?
    2) using RBO in the 10g or higher can make other Unexpected, Serious problem?
    3) Do you really want to close supporting the RBO?
    4) Is it wrong using RBO in the 10g or higher ?
    Thanks in Advance, Oracle and Other Experts or People who have the experiece
    about the RBO in Oracle 10g or higer.

    2) using RBO in the 10g or higher can make other Unexpected, Serious problem?If you are really using 10g then you ought to learn how to use all its features properly. This means learning how Cost-Based Optimization works. You should do this as much as a favour to yourself and your career prospects as for any other reason.
    If your database is small enough that the RBO provides sufficiently effective performance then you can get away with it. But in the long run CBO is definitely the way to go.
    Cheers, APC
    blog: http://radiofreetooting.blogspot.com/

  • Facin problems in the 'Select... for all entries'

    I am facing problem with this piece of code, please share ur thoughts on it. I have specified the inputs.
    I am extracting the open items from the BSIS table for specified 3 account number.
    Inputs to the prg:
    field     No. of values
    r_bukrs       1
    r_hkont      2
    r_blart     6
    r_budat  date range of 1 yr
    r_bldat  nil
    v_tosdef contain 1 account number
    " In each FI document posted, one line will have the 'v_tosdef' account number and one account from the 'r_hkont' values."
    So will this query efficient.
      SELECT bukrs
             hkont
             gjahr
             belnr
             budat
             bldat
             xblnr
             blart
             shkzg
             dmbtr
        FROM bsis
        INTO TABLE i_bsis
       WHERE bukrs IN r_bukrs                    " Company code
         AND hkont =  v_tosdef                  " Account number
         AND budat IN r_budat                    " Posting date
         AND bldat IN r_bldat                    " Document date
         AND blart IN r_blart.                   " Document type
      IF sy-subrc <> 0.
        MESSAGE i003.
        STOP.
      ENDIF.
    *@ Collecting the BELNR & GJAHR From the extracted records
      li_bsis[] = i_bsis[].
      SORT li_bsis BY bukrs gjahr belnr.
      DELETE ADJACENT
      DUPLICATES FROM li_bsis
            COMPARING bukrs gjahr belnr.
      IF NOT li_bsis[] IS INITIAL.
        SELECT bukrs
               hkont
               gjahr
               belnr
               budat
               bldat
               xblnr
               blart
               shkzg
               dmbtr
          FROM bsis
    APPENDING TABLE i_bsis
           FOR ALL ENTRIES IN li_bsis
         WHERE bukrs = li_bsis-bukrs               " Company code
           AND hkont IN r_hkont                    " Account number
           AND gjahr =  li_bsis-gjahr              " Fiscal year
           AND belnr =  li_bsis-belnr.             " Document num
    BSIS table size around 86GB
    primary index size aroung 33GB
    and the index quality is 54%
    the CBO shows less cost, but the actual runs takes too much disk read's / bgets..
    Message was edited by:
            Sandy

    Hi Sandy,
    You indicated the size of the tables and index, what is the total number of records in your BSIS?
    In your range tables, make sure they are postive formed.
    Ex. r_bukrs :  I EQ '1001', and not I NE '1000'.
    You should consider coding your statements to check for input for bldat, code it with r_bldat and then another set without. It should be better performance to not have empty where conditions. So two routines, Selects with bldat and without.
    Don't know if you have a Basis person to help analyze the performance, but you should look at the indexes in BSIS. You may have several indexes that contain some of your input fields but they may be spread across several indexes or there may be none. But say you have 5 indexes and it happens that just one of your parameters are in each of those indexes. Well, it can only use one index so while you think you are providing alot of parameters to help performance only one field is being used to access the index. What you need to do then is to find an index that has the most fields in your where clause and see if you can add to that, so long it's not an SAP index. If it's a z index consider adding additional fields to it, or consider creating a new index.
    You can at least analyze the first Select in your DEV client. Run a trace, ST05 and then execute your code. It will show you which index it has used if any.
    Also, look at the query values it is passing to the database. You said you get 6 M records on the first Select. This just seem like a lot of records, which is for just one account number (v_tosdef) along with the other parameters. I'm wondering if there's a problem with your input data. With 6M in your first table, your FOR ALL ENTRIES statement will be executed 1.2 million times. Tyically the database interface breaks down your Select-For All entries statement into 5 records per query. Again, run ST05 and you will see this.
    In SE16, on your BSIS table, what is your count of records if you enter only the account number?
    As a test, you might want to try entering all your parameters in SE16, run ST05 to trace the SQL to see what it is doing. You may have to kill your SE16 session or it may time out on you. You can stop your ST05 trace before your SE16 finishes and it will still show how SAP is going after the data and what index it used.
    Let me know if this helped any.
    Regards,
    Filler

  • 11g and ORA-04030 problems

    We have a new Dell server, OS Windows 2003 Server Enterprise 32bit with 32GB or RAM in it. Right now 64bit is not available to us because of Vendor issues so I can't go down that road yet. I keep running into ORA-04030 errors whether I put in the /3GB /USERVA=2560 switches or not. I got the /USERVA setting from Oracle's Best Practices for Windows Servers Guide. This new server is our current test box so we can upgrade our main application to 11g. Our current production server is running 10g and is set up the exact same way as this one using the same application, just on 10g. The only difference is that on 11g I am using Automatic Memory Management, it is at 11.1.0.6 right now. I plan to bump it up to 11.1.0.7 soon though.
    The problem happens when Oracle.exe uses memory up to the limit of the Memory_target setting, then it throws the ORA-04030 error. It is like the process is reaching the Memory_target and then not using the memory it has, it is trying to grab more from the OS. I have tried setting this target lower and higher with the same results. I have also tried with and without the /3gb switch, same results. Dell hasn't offered much information, they told me to try Large Page Support.
    I am at a loss, any help would be appreciated.

    Thanks for the suggestions so far. This is what I got back from my vendor. It is possibly due to an unpublished Bug 7330813 that has to do with Function Based Indexes. This bug is fixed in 11.2.
    -Unpublished Bug 7330813 deails
    CBO may incur high hard parse times (as compared to 10g) for queries involving
    Tables with functional indexes.
    This Fix complements the fix for unpublished bug 6194582.
    Workaround:
    Set "_replace_virtual_columns"=false;
    I have set the above parameter so we will see if it helps. Keep in mind that Oracle says not to use this Initialization parameter unless told to do so by Oracle Support.

  • Enq: TX - row lock contention problem

    Hi ,
    Db version 10.2.0.4
    os solaris.
    i have upgraded my database from 9.2.0.4 to 10.2.0.4 by using exp/imp as my database is small.
    I have created new instance of 10g and changed parameter values as 9i(as required). then imported from 9i to 10g instance.
    After importing in 10g instance we are face application wide performance problem..the response time of the applicatoin was very slow...
    i have taken awr report of various times and have seeen
    SELECT puid,ptimestamp FROM PPOM_OBJECT WHERE puid IN (:1) FOR UPDATE
    this query is causing the problem..enq: TX - row lock contention
    Cache Sizes
    ~~~~~~~~~~~                       Begin        End
                   Buffer Cache:       756M       756M  Std Block Size:         8K
               Shared Pool Size:       252M       252M      Log Buffer:     1,264K
    Load Profile
    ~~~~~~~~~~~~                            Per Second       Per Transaction
                      Redo size:              2,501.54              3,029.25
                  Logical reads:              2,067.79              2,504.00
                  Block changes:                 17.99                 21.78
                 Physical reads:                  0.02                  0.03
                Physical writes:                  0.41                  0.50
                     User calls:                140.74                170.44
                         Parses:                139.55                168.99
                    Hard parses:                  0.01                  0.01
                          Sorts:                 10.65                 12.89
                         Logons:                  0.32                  0.38
                       Executes:                139.76                169.24
                   Transactions:                  0.83
      % Blocks changed per Read:    0.87    Recursive Call %:    17.60
    Rollback per transaction %:    0.00       Rows per Sort:    16.86
    Instance Efficiency Percentages (Target 100%)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                Buffer Nowait %:  100.00       Redo NoWait %:  100.00
                Buffer  Hit   %:  100.00    In-memory Sort %:  100.00
                Library Hit   %:  100.03        Soft Parse %:  100.00
             Execute to Parse %:    0.15         Latch Hit %:   99.89
    Parse CPU to Parse Elapsd %:   93.19     % Non-Parse CPU:   94.94
    Shared Pool Statistics        Begin    End
                 Memory Usage %:   86.73   86.55
        % SQL with executions>1:   90.99   95.33
      % Memory for SQL w/exec>1:   79.15   90.58
    Top 5 Timed Events                                         Avg %Total
    ~~~~~~~~~~~~~~~~~~                                        wait   Call
    Event                                 Waits    Time (s)   (ms)   Time Wait Class
    CPU time                                            397          86.3
    enq: TX - row lock contention           508          59    115   12.7 Applicatio
    log file sync                         2,991           5      2    1.1     Commit
    log file parallel write               3,238           5      2    1.1 System I/O
    SQL*Net more data to client          59,871           4      0    1.0    Network
    ^LTime Model Statistics              DB/Inst: WGMUGPR2/wgmugpr2  Snaps: 706-707
    -> Total time in database user-calls (DB Time): 460.5s
    -> Statistics including the word "background" measure background process
       time, and so do not contribute to the DB time statistic
    -> Ordered by % or DB time desc, Statistic name
                                                                       Avg
                                                 %Time  Total Wait    wait     Waits
    Event                                 Waits  -outs    Time (s)    (ms)      /txn
    enq: TX - row lock contentio            508     .0          59     115       0.2
    log file sync                         2,991     .0           5       2       1.0
    log file parallel write               3,238     .0           5       2       1.1
    SQL*Net more data to client          59,871     .0           4       0      20.1
    control file parallel write           1,201     .0           1       1       0.4
    SQL*Net more data from clien          3,393     .0           1       0       1.1
    SQL*Net message to client           509,864     .0           1       0     170.9
    os thread startup                         3     .0           1     196       0.0
    db file parallel write                  845     .0           1       1       0.3
    -> % Total DB Time is the Elapsed Time of the SQL statement divided
       into the Total Database Time multiplied by 100
      Elapsed      CPU                  Elap per  % Total
      Time (s)   Time (s)  Executions   Exec (s)  DB Time    SQL Id
            59          1        1,377        0.0    12.9 bwnt27fp0z3gm
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    SELECT puid,ptimestamp FROM PPOM_OBJECT WHERE puid IN (:1) FOR UPDATE
            41         41          459        0.1     8.9 8cdswsp7cva2h
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    select rpad(argument_name, 32, ' ') || in_out || ' ' || nvl(type_subname, data_t
    ype) info from user_arguments where package_name IS NULL and object_name = uppe
    r(:1) and argument_name is not null order by object_name, position
            39         38        7,457        0.0     8.4 271hn6sgra2d8
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    SELECT DISTINCT t_0.puid FROM PIMANTYPE t_0 WHERE (UPPER(t_0.ptype_name) = UPPER
    (:1))
            23         22          459        0.0     4.9 g92t08k78tgrw
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    SELECT PIMANTYPE.puid, ptimestamp, ppid, rowning_siteu, rowning_sitec, pis_froze
    n, ptype_class, ptype_name FROM PPOM_OBJECT, PIMANTYPE WHERE PPOM_OBJECT.puid =
    (PIMANTYPE.puid)
            22         22      158,004        0.0     4.9 chqpmv9c05ghq
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    SELECT puid,ptimestamp FROM PPOM_OBJECT WHERE puid = :1
            17         17        2,294        0.0     3.7 3n5trh11n1x8w
    Module: syncdizio_op@snstr09 (TNS V1-V3)
    SELECT PTYPECANNEDMETHOD.puid, ptimestamp, ppid, rowning_siteu, rowning_sitec, p
    is_frozen, pobject_desc, psecure_bits,VLA_344_5, pmethod_name, pmsg_name, ptype_
    name, pexec_seq, paction_type FROM PPOM_OBJECT,PBUSINESSRULE, PTYPECANNEDMETHOD
    WHERE PTYPECANNEDMETHOD.puid IN (:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,in 9i there is a parameter ENQUEUE_RESOURCES but in 10g relese 2 its got obsoleted....
    am new to performace tunning please advice me....!
    Regards
    Vamshi

    The CBO has changed substantially between 9.2.x and 10.2.x. Pl see MOS Doc 754931.1 (Cost Based Optimizer - Common Misconceptions and Issues - 10g and Above). Pl verify that statistics have been gathered and are current - pl see MOS Doc 605439.1 (Master Note: Recommendations for Gathering Optimizer Statistics on 10g).
    Looking at your output, it seems to me that the database is entirely CPU-bound. 86.3% of time is spent on CPU. The last 5 SQL statements in the output, all of the elapsed time is spent on CPU.
    Pl post your init.ora parameters, along with your hardware specs. This question might be more appropriate in the "Database - General" forum.
    HTH
    Srini

Maybe you are looking for