Explain the rows returned in a group plan of

I have a (select statement) that returns 18 rows.

wrap a select statement that is nested in a group by around it

Select col_a, col_b of
(select statement)
Group of col_a, col_b

Returns even 18 rows as expected

explain that she and I see the 18 rows returned to Id 2 and the Group hash by, and then select lines 1.
                    
------------------------------------------------------------------------------------------------------------------------------------------------------                              
| Id  | Operation                                   | Name                           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |                              
------------------------------------------------------------------------------------------------------------------------------------------------------                              
|   0 | SELECT STATEMENT                            |                                |     1 |    95 |       | 90897  (75)| 00:00:02 |       |       |                              
|   1 |  HASH GROUP BY                              |                                |     1 |    95 |       | 90897  (75)| 00:00:02 |       |       |                              
|   2 |   VIEW                                      |                                |    18 |  1710 |       | 90896  (75)| 00:00:02 |       |       |        
reason Im asking is I rewrote the SQL code in the internal instruction for adjustment purposes and I get even 18 rows as expected but now I have 2 lines referred to the hash group by.
-----------------------------------------------------------------------------------------------------------------------------------------------------                               
| Id  | Operation                                  | Name                           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |                               
-----------------------------------------------------------------------------------------------------------------------------------------------------                               
|   0 | SELECT STATEMENT                           |                                |     2 |   190 |       | 82657  (80)| 00:00:02 |       |       |                               
|   1 |  HASH GROUP BY                             |                                |     2 |   190 |       | 82657  (80)| 00:00:02 |       |       |                               
|   2 |   VIEW                                     |                                |    18 |  1710 |       | 82656  (80)| 00:00:02 |       |       |                               
..
..
In regards to plans above that "lines" means for the hash group by.

These are just estimates, not actually the rows returned.

Sometimes, you can make this small change and a kind of funny the optimizer calculation may change.

But that's just an estimate.

Tags: Database

Similar Questions

  • How to limit the rows returned from the user role-based interactive reports

    Hello

    I'm a new Apex-PL/SQL Developer, looking for some recommendations on how to implement an interactive report to display different lines in your current application ROLE service.

    For example let's say you have an application for orders and 2 different roles: superuser and sales-rep

    Now, if super user connects to the application, it should be able to see all the rows in the orders table, however, if the user 'john' connects with the commercial list, he should see those orders assigned to him.

    I don't think I can use "dynamic" sql and build my where clause on the fly if I choose an interactive report so I was looking around and came across the concept of a common function but it seems that some other people do this with collections of the APEX. Is there anyone with a recommendation for one to use? A few books I've read recommend putting most of the logic that you can on your database (easier to maintain in the long term) that's why I thought about pipep functions using, but I thought I would check with the experts first.

    Thank you!

    If you are allowed to use an Enterprise Edition database and to apply these restrictions, through the entire application, or across multiple applications, then use of private virtual database (DPV), with the security attributes of PL/SQL Code to the initialization/cleanup APEX application to set and reset the settings in your application.

    Should you not use EE, then you can roll your own VPD use parameterized views.

    If the restriction is only required for this unique IR, then, simply use a union of two mutually exclusive predicates opportunities:

    select ...
    from orders su
    where :app_role = 'super-user'
    union all
    select ...
    from orders rep
    where :app_role = 'sales-rep'
    and rep.salesman = :app_user
    

    All of these approaches should outperform functions in pipeline, collections, or a user-defined function (which, in a predicate that is executed for each line, mudra stopped the large datasets because of context switching).

  • Sort order by default of the rows returned by a query

    Hello

    We have a query that returns rows sorted by ascending order on an Oracle 9i server. Example of returned rows.

    879

    Billing account number

    Team account

    ACCT No.

    The action code

    ADMIRE

    Alternative Service instance

    Circuit #.

    Associate Circuit #-2

    Automatic return action

    See BMO Auto

    APR

    We have the same query that returns rows with a random order when ran on an Oracle 11 g database that we plan to upgrade at. example of lines.

    PAIR1 - L02

    Secondary XSLAM of the Board

    The identifier of the current command

    Right stick DSL wholesale

    RICI. PP

    Circuit protection

    For the DSL Service provider contact

    Secondary XSLAM CLLI

    BP1 - L05

    The service status

    MTTR7Indicator

    PAIR2 - L04

    ADMIRE

    Need help

    We demand that the lines to be pre-sorted as 9i to avoid external sort in order by clause. Why is the difference in query returned lines differ between them when tables and indexes that are affected by the query have been matching exactly the other environment.

    Additional information:

    Oracle 9i database character set: AL32UTF8

    Oracle 11 g database character set: WE8MSWIN1252

    Please let me know if you need additional information.

    Thank you!

    If your query is a group, 9i, the Group of the operation has been done as a SORT operation the returned results are sorted.

    10g, the default behavior for the group by being a HASH AGGREGATION, which means that the results are not sorted.

    Support.oracle.com or search google for "_gby_hash_aggregation_enabled", which is a parameter that controls this behavior.

    Hemant K Collette

  • Not the rows returned by the spatial query wrapped in SELECT * FROM...

    Hello

    When you run a query with SDO_EQUAL sub, I get a very strange behavior. The SDO_EQUAL query on its own works very well, but if I wrap in SELECT * from there, I get no results. If I wrap SDO_ANYINTERACT in SELECT * from there, I get the expected result.

    It seems like the spatial index is used during the execution of the ordinary, but not when SDO_EQUAL request wrapped in SELECT * FROM. Weird. The spatial index is also not used when SDO_ANYINTERACT is wrapped in SELECT * FROM... so I don't know why that returns the correct answer.

    I get this problem on 11.2.0.2 on Red Hat Linux 64-bit and 11.2.0.1 on Windows XP 32-bit (i.e., all versions of 11g I've tried). The query works as expected on 10.2.0.5 on Windows Server 2003 64-bit.

    Any ideas?

    Confused in Dublin (John)

    Test case...
    SQL> 
    SQL> -- Create a table and insert the same geometry twice
    SQL> DROP TABLE sdo_equal_query_test;
    
    Table dropped.
    
    SQL> CREATE TABLE sdo_equal_query_test (
      2  id NUMBER,
      3  geometry SDO_GEOMETRY);
    
    Table created.
    
    SQL> 
    SQL> INSERT INTO sdo_equal_query_test VALUES (1,
      2  SDO_GEOMETRY(3003, 81989, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
      3  SDO_ORDINATE_ARRAY(1057.39, 1048.23, 4, 1057.53, 1046.04, 4, 1057.67, 1043.94, 4, 1061.17, 1044.60, 5, 1060.95, 1046.49, 5, 1060.81, 1047.78, 5, 1057.39, 1048.23, 4)));
    
    1 row created.
    
    SQL> 
    SQL> INSERT INTO sdo_equal_query_test VALUES (2,
      2  SDO_GEOMETRY(3003, 81989, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
      3  SDO_ORDINATE_ARRAY(1057.39, 1048.23, 4, 1057.53, 1046.04, 4, 1057.67, 1043.94, 4, 1061.17, 1044.60, 5, 1060.95, 1046.49, 5, 1060.81, 1047.78, 5, 1057.39, 1048.23, 4)));
    
    1 row created.
    
    SQL> 
    SQL> -- Setup metadata
    SQL> DELETE FROM user_sdo_geom_metadata WHERE table_name = 'SDO_EQUAL_QUERY_TEST';
    
    1 row deleted.
    
    SQL> INSERT INTO user_sdo_geom_metadata VALUES ('SDO_EQUAL_QUERY_TEST','GEOMETRY',
      2  SDO_DIM_ARRAY(SDO_DIM_ELEMENT('X', 0, 100000, .0001), SDO_DIM_ELEMENT('Y', 0, 100000, .0001), SDO_DIM_ELEMENT('Z', -100, 4000, .0001))
      3  ,81989);
    
    1 row created.
    
    SQL> 
    SQL> -- Create spatial index
    SQL> DROP INDEX sdo_equal_query_test_spind;
    DROP INDEX sdo_equal_query_test_spind
               *
    ERROR at line 1:
    ORA-01418: specified index does not exist
    
    
    SQL> CREATE INDEX sdo_equal_query_test_spind ON sdo_equal_query_test(geometry) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
    
    Index created.
    
    SQL> 
    SQL> -- Ensure data is valid
    SQL> SELECT sdo_geom.validate_geometry_with_context(sdo_cs.make_2d(geometry), 0.0001) is_valid
      2  FROM sdo_equal_query_test;
    
    IS_VALID
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    TRUE
    TRUE
    
    2 rows selected.
    
    SQL> 
    SQL> -- Check query results using sdo_equal
    SQL> SELECT b.id
      2  FROM sdo_equal_query_test a, sdo_equal_query_test b
      3  WHERE a.id = 1
      4  AND b.id != a.id
      5  AND sdo_equal(a.geometry, b.geometry) = 'TRUE';
    
            ID
    ----------
             2
    
    1 row selected.
    
    SQL> 
    SQL> -- Check query results using sdo_equal wrapped in SELECT * FROM
    SQL> -- Results should be the same as above, but... no rows selected
    SQL> SELECT * FROM (
      2       SELECT b.id
      3       FROM sdo_equal_query_test a, sdo_equal_query_test b
      4       WHERE a.id = 1
      5       AND b.id != a.id
      6       AND sdo_equal(a.geometry, b.geometry) = 'TRUE'
      7  );
    
    no rows selected
    
    SQL> 
    SQL> -- So that didn't work.  Now try sdo_anyinteract... this works ok
    SQL> SELECT * FROM (
      2       SELECT b.id
      3       FROM sdo_equal_query_test a, sdo_equal_query_test b
      4       WHERE a.id = 1
      5       AND b.id != a.id
      6       AND sdo_anyinteract(a.geometry, b.geometry) = 'TRUE'
      7  );
    
            ID
    ----------
             2
    
    1 row selected.
    
    SQL> 
    SQL> -- Now try a scalar query
    SQL> SELECT * FROM (
      2       SELECT b.id
      3       FROM sdo_equal_query_test a, sdo_equal_query_test b
      4       WHERE a.id = 1
      5       AND b.id != a.id
      6  );
    
            ID
    ----------
             2
    
    1 row selected.
    
    SQL> spool off
    Here is the plan of the explain output for the query that works. Note that the spatial index is used.
    SQL> EXPLAIN PLAN FOR
      2  SELECT b.id
      3  FROM sdo_equal_query_test a, sdo_equal_query_test b
      4  WHERE a.id = 1
      5  AND b.id != a.id
      6  AND sdo_equal(a.geometry, b.geometry) = 'TRUE';
    
    Explained.
    
    SQL> @?/rdbms/admin/utlxpls.sql
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------
    Plan hash value: 3529470109
    
    ------------------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                            |     1 |  7684 |     3   (0)| 00:00:01 |
    |   1 |  RESULT CACHE                 | f5p63r46pbzty4sr45td1uv5g8 |       |       |            |       |
    |   2 |   NESTED LOOPS                |                            |     1 |  7684 |     3   (0)| 00:00:01 |
    |*  3 |    TABLE ACCESS FULL          | SDO_EQUAL_QUERY_TEST       |     1 |  3836 |     3   (0)| 00:00:01 |
    |*  4 |    TABLE ACCESS BY INDEX ROWID| SDO_EQUAL_QUERY_TEST       |     1 |  3848 |     3   (0)| 00:00:01 |
    |*  5 |     DOMAIN INDEX              | SDO_EQUAL_QUERY_TEST_SPIND |       |       |     0   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - filter("B"."ID"!=1)
       4 - filter("A"."ID"=1 AND "B"."ID"!="A"."ID")
       5 - access("MDSYS"."SDO_EQUAL"("A"."GEOMETRY","B"."GEOMETRY")='TRUE')
    ..... other stuff .....     
    Here is the plan of the explain output for the query is not working. Note that the spatial index is not used.
    SQL> EXPLAIN PLAN FOR
      2  SELECT * FROM (
      3     SELECT b.id
      4     FROM sdo_equal_query_test a, sdo_equal_query_test b
      5     WHERE a.id = 1
      6     AND b.id != a.id
      7     AND sdo_equal(a.geometry, b.geometry) = 'TRUE'
      8  );
    
    Explained.
    
    SQL> @?/rdbms/admin/utlxpls.sql
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------------------------
    Plan hash value: 1024466006
    
    --------------------------------------------------------------------------------------------------
    | Id  | Operation           | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |                            |     1 |  7684 |     6   (0)| 00:00:01 |
    |   1 |  RESULT CACHE       | 2sd35wrcw3jr411bcg3sz161f6 |       |       |            |          |
    |   2 |   NESTED LOOPS      |                            |     1 |  7684 |     6   (0)| 00:00:01 |
    |*  3 |    TABLE ACCESS FULL| SDO_EQUAL_QUERY_TEST       |     1 |  3836 |     3   (0)| 00:00:01 |
    |*  4 |    TABLE ACCESS FULL| SDO_EQUAL_QUERY_TEST       |     1 |  3848 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - filter("B"."ID"!=1)
       4 - filter("A"."ID"=1 AND "B"."ID"!="A"."ID" AND
                  "MDSYS"."SDO_EQUAL"("A"."GEOMETRY","B"."GEOMETRY")='TRUE')
    ..... other stuff .....               

    Yes, this is the bug 9740355. You can get a 11.2.0.1 patch, or wait for 11.2.0.3.

  • Limit the rows returned from a sql prompt of dashboard

    Hello

    I use the following sql in the dash prompt to generate a list of values:
    SELECT LEFT (MONTHNAME ("begins and ends in days". (("" Start date "), 3) | » -'|| RIGHT (CAST (YEAR ("begins and ends in days". ((("" Start date ") AS VARCHAR (4)), 2) FROM the"metric"where"begins and ends in days. "" Start date "< = TIMESTAMPADD(SQL_TSI_MONTH, 1,current_date) ORDER BY 'Start and End Days '. "' Start date ' DESC
    which gives me an output like MAY-13,APR-13,MAR-13,FEB-13,JAN-13,DEC-12...;

    Is there a way to limit the release until FEB - 13...

    Thank you
    Sunny

    Use this
    where ' start and end days '. " Start date.<=TIMESTAMPADD(SQL_TSI_MONTH,>
    and "start and end days '." Start date "> = TIMESTAMPADD (SQL_TSI_MONTH,-2, current_date)"

    Check if help

  • Filtering the records returned in a group

    I previously used to filter records:
    <?-foreach: (current group) [. / COURSE_ORDER > 13]? >

    This takes care with 'and' or 'between '? Need to pull a specific range, but do not know what syntax works
    That is to say.
    <?-foreach: (current group) [. / > 13 COURSE_ORDER] and [. / COURSE_ORDER < 100]? >

    Check like that...

    13 and COURSE_ORDER<>

    Thank you
    Ananth

  • Explain plan - index range scan lines increase while access to the table by the row id

    I use Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64 bit Production. Please help me understand why the rows returned from the index range scan is 3 but access the table by row index 10155 id. Please refer to explain the plan ID 7 and 8.


    PLAN_TABLE_OUTPUT                                                                                   
    ----------------------------------------------------------------------------------------------------
                                                                                                        
    ---------------------------------------------------------------------------------------------       
    | Id  | Operation                      |  Name                      | Rows  | Bytes | Cost  |       
    ---------------------------------------------------------------------------------------------       
    |   0 | SELECT STATEMENT               |                            |  8308 |   446K|  4408 |       
    |   1 |  SORT ORDER BY                 |                            |  8308 |   446K|  4408 |       
    |*  2 |   HASH JOIN                    |                            |  8308 |   446K|  4316 |       
    |*  3 |    HASH JOIN                   |                            |  8189 |   255K|  2256 |       
    |*  4 |     INDEX FAST FULL SCAN       | TUNE_CHD_07                |  8071 | 72639 |   199 |       
    |*  5 |     TABLE ACCESS BY INDEX ROWID| CLM_HDR_CLM_LN_STATUS      | 10155 |   228K|  2055 |       
    |*  6 |      INDEX RANGE SCAN          | XIF3CLM_HDR_CLM_LN_STATUS  |     3 |       |   120 |       
    |*  7 |    TABLE ACCESS BY INDEX ROWID | CLM_HDR_CLM_LN_STATUS      | 10155 |   228K|  2055 |       
    |*  8 |     INDEX RANGE SCAN           | XIF3CLM_HDR_CLM_LN_STATUS  |     3 |       |   120 |       
    ---------------------------------------------------------------------------------------------       
                                                                                                        
    Predicate Information (identified by operation id):                                                 
    ---------------------------------------------------                                                 
                                                                                                        
       2 - access("CHCLS"."CLAIM_HEADER_SID"="CHCLS1"."CLAIM_HEADER_SID")                               
       3 - access("CHD"."CLAIM_HEADER_SID"="CHCLS"."CLAIM_HEADER_SID")                                  
       4 - filter("CHD"."CLM_TYPE_CID"=2)                                                               
       5 - filter("CHCLS"."CLAIM_LINE_SID" IS NULL AND "CHCLS"."TO_DATE" IS NULL)                       
       6 - access("CHCLS"."STATUS_TYPE_CID"=8 AND "CHCLS"."STATUS_CID"=71)                              
       7 - filter("CHCLS1"."CLAIM_LINE_SID" IS NULL AND "CHCLS1"."TO_DATE" IS NULL)                     
       8 - access("CHCLS1"."STATUS_TYPE_CID"=2 AND "CHCLS1"."STATUS_CID"=130)                           
                                                                                                        
    Note: cpu costing is off                                                                            
    Thanks a lot for all the help...
  • Order in which the rows are returned from an external table

    Hello
    Anyone know if I can count on the rows returned in the order with a selection of Ext_table.
    For example:

    SELECT * FROM MY_EXT_TAB

    Where MY_EXT_TAB is a file read
    1
    2
    3

    The query will return to the top of the file down, that is to say 1-3.

    Thank you very much.

    Hello

    To get the number of the record since the beginning of the file, you can use the MASS_ADDITION_ID parameter in the external Table definition:

    http://download.Oracle.com/docs/CD/B19306_01/server.102/b14215/ldr_field_list.htm#sthref1264

    You define a column:

     RECNUM
    

    Then, in your application, you can use the operator order of this column.

    In this way, you ensure that you always comply with the registration order in the file.

    Hope this helps.
    Best regards
    Jean Valentine

  • Explain the different Plans

    Hello

    in 11.2.0.3 the same query on two different DBs (on the same server) have different explain Plans (differnet number of rows returned 9690K vs M 14):

    DBDEV:

    ---------------------------------------------------------------------------------------------

    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

    ---------------------------------------------------------------------------------------------

    |   0 | INSERT STATEMENT.                  |  9690K |  4482M |   344K (1) | 01:08:49 |

    |   1.  LOAD TABLE CLASSIC | PS_PROJ_RES_TA14 |       |       |            |          |

    |*  2 |   TABLE ACCESS FULL | PS_PROJ_RESOURCE |  9690K |  4482M |   344K (1) | 01:08:49 |

    ---------------------------------------------------------------------------------------------

    DBTST

    ---------------------------------------------------------------------------------------------

    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

    ---------------------------------------------------------------------------------------------

    |   0 | INSERT STATEMENT.                  |    14 M |  6534M |   344K (1) | 01:08:50 |

    |   1.  LOAD TABLE CLASSIC | PS_PROJ_RES_TA14 |       |       |            |          |

    |*  2 |   TABLE ACCESS FULL | PS_PROJ_RESOURCE |    14 M |  6534M |   344K (1) | 01:08:50 |

    ---------------------------------------------------------------------------------------------

    The optimizer settings are the same:

    VALUE OF TYPE NAME

    optimizer_capture_sql_plan_baselines boolean FALSE

    optimizer_dynamic_sampling integer 2

    optimizer_features_enable string 11.2.0.3

    optimizer_index_caching integer 0

    OPTIMIZER_INDEX_COST_ADJ integer 100

    the string ALL_ROWS optimizer_mode

    optimizer_secure_view_merging boolean TRUE

    optimizer_use_invisible_indexes boolean FALSE

    optimizer_use_pending_statistics boolean FALSE

    Boolean optimizer_use_sql_plan_baselines TRUE

    And the number of lines:

    In DBTST

    Select Count (*) from ps_proj_resource

    COUNT(*)

    --------

    18072893

    In DBDEV

    COUNT(*)

    --------

    18070581

    Thanks for the explanation and ideas.

    Hello

    Yes will not change the plan to explain it, but the number of rows must / may change in the case otherwise we must understand why the number of rows returned is so different (14 M against 9M) with almost the same number of rows in the PS_PROJ_RESOURCE table.

    Thank you and best regards.

  • How to write a function to estimate the number of rows returned SQL?

    How to write a function to estimate the number of rows returned SQL through SQL Execution Plan?
    My idea is
    Call dbms_sql.parse to create the SQL PLAN, then ask the PLAN for the number of estimated return lines.
    But how to get SQL plan through "id cursor?
    Thank you.

    You can use EXECUTE IMMEDIATE to explain plan statement. About the STATEMENT_ID generation, it could be anything. Even a SYSTIMESTAMP cast as TANK would work.

  • Explain the plans differ as the parameter value changes

    Hi all

    My colleague posted a similar question a few days before. Happened because of some bad index. But now we are in a strange situation.

    DB:
    SQL> select * from v$version;
    
    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
    PL/SQL Release 10.2.0.1.0 - Production
    CORE    10.2.0.1.0      Production
    TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
    NLSRTL Version 10.2.0.1.0 - Production
    We use the query below and was working fine until 13.
    SQL> explain plan for
      2  SELECT *
      3    FROM gacc_dtl_v1  acc,
      4         gcus_dtl_v1  cus,
      5         gtxn_dtl_v1  txn
      6   WHERE txn.customer_id = cus.customer_number(+)
      7   AND txn.batch_id = cus.batch_id(+)
      8   AND txn.account_number = acc.id
      9   AND acc.batch_id = '130609'
     10   AND cus.batch_id(+) = '130609'
     11   AND txn.batch_id = '130609' AND cus.target IN ('30');
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    -------------------------------------------------------------------------------------------------------------
    Plan hash value: 566819363
    
    -------------------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name                | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                     |     1 |   947 |       | 16963   (1)| 00:03:24 |
    |   1 |  NESTED LOOPS                 |                     |     1 |   947 |       | 16963   (1)| 00:03:24 |
    |*  2 |   HASH JOIN                   |                     |    41 | 26322 |  9136K| 16799   (1)| 00:03:22 |
    |*  3 |    TABLE ACCESS BY INDEX ROWID| GTXN_DTL_V1         | 31055 |  8764K|       |  2430   (1)| 00:00:30 |
    |*  4 |     INDEX RANGE SCAN          | GTXN_V1_BATCHID_NDX | 60524 |       |       |   156   (2)| 00:00:02 |
    |*  5 |    TABLE ACCESS BY INDEX ROWID| GCUS_DTL_V1         |   176K|    59M|       | 10869   (1)| 00:02:11 |
    |*  6 |     INDEX RANGE SCAN          | IDX_CUS2_V1         |   198K|       |       |   527   (2)| 00:00:07 |
    |   7 |   TABLE ACCESS BY INDEX ROWID | GACC_DTL_V1         |     1 |   305 |       |     4   (0)| 00:00:01 |
    |*  8 |    INDEX RANGE SCAN           | GACC_DTL_V1_IDX     |     1 |       |       |     3   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("TXN"."CUSTOMER_ID"="CUS"."CUSTOMER_NUMBER" AND "TXN"."BATCH_ID"="CUS"."BATCH_ID")
       3 - filter("TXN"."CUSTOMER_ID" IS NOT NULL)
       4 - access("TXN"."BATCH_ID"='130609')
       5 - filter("CUS"."TARGET"='30')
       6 - access("CUS"."BATCH_ID"='130609')
       8 - access("TXN"."ACCOUNT_NUMBER"="ACC"."ID" AND "ACC"."BATCH_ID"='130609')
           filter(SUBSTR("TXN"."ACCOUNT_NUMBER",1,3)=SUBSTR("ACC"."ID",1,3))
    
    26 rows selected.
    It shows a hash join and nested with cost 16963 loops and gives the result in 2-3 seconds. It gives the same plan to explain even now if we use batch_id = '130609'

    Now all of a sudden from yesterday it gives different explain the plan below. Only difference in the query below is the value of batch_id
    SQL> explain plan for
      2  SELECT *
      3    FROM gacc_dtl_v1  acc,
      4         gcus_dtl_v1  cus,
      5         gtxn_dtl_v1  txn
      6   WHERE txn.customer_id = cus.customer_number(+)
      7   AND txn.batch_id = cus.batch_id(+)
      8   AND txn.account_number = acc.id
      9   AND acc.batch_id = '150609'
     10   AND cus.batch_id(+) = '150609'
     11   AND txn.batch_id = '150609' AND cus.target IN ('30');
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------
    Plan hash value: 773603995
    
    --------------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                        |     1 |   947 |    77   (0)| 00:00:01 |
    |   1 |  NESTED LOOPS                 |                        |     1 |   947 |    77   (0)| 00:00:01 |
    |   2 |   NESTED LOOPS                |                        |     1 |   594 |    73   (0)| 00:00:01 |
    |   3 |    TABLE ACCESS BY INDEX ROWID| GACC_DTL_V1            |     1 |   305 |     4   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | GACC_DTL_BATCH_ID_INDX |     1 |       |     3   (0)| 00:00:01 |
    |*  5 |    TABLE ACCESS BY INDEX ROWID| GTXN_DTL_V1            |     1 |   289 |    69   (0)| 00:00:01 |
    |*  6 |     INDEX RANGE SCAN          | IDX_TXN2_V1            |   125 |       |    12   (0)| 00:00:01 |
    |*  7 |   TABLE ACCESS BY INDEX ROWID | GCUS_DTL_V1            |     1 |   353 |     4   (0)| 00:00:01 |
    |*  8 |    INDEX RANGE SCAN           | IDX_CUS3_V1            |     1 |       |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       4 - access("ACC"."BATCH_ID"='150609')
       5 - filter("TXN"."CUSTOMER_ID" IS NOT NULL AND "TXN"."BATCH_ID"='150609')
       6 - access("TXN"."ACCOUNT_NUMBER"="ACC"."ID")
           filter(SUBSTR("TXN"."ACCOUNT_NUMBER",1,3)=SUBSTR("ACC"."ID",1,3))
       7 - filter("CUS"."TARGET"='30')
       8 - access("CUS"."BATCH_ID"='150609' AND "TXN"."CUSTOMER_ID"="CUS"."CUSTOMER_NUMBER")
           filter("TXN"."BATCH_ID"="CUS"."BATCH_ID")
    
    26 rows selected.
    It shows two loops nested with cost 77, but works for hours. Very very slow.. No idea what's going on...
     select i.table_name,i.index_name,index_type,c.column_name,c.column_position,e.column_expression
       from all_indexes i, all_ind_columns c,all_ind_expressions e
       where c.index_name = i.index_name
       and e.index_name(+) = i.index_name
       and i.table_name in ('GCUS_DTL_V1','GACC_DTL_V1','GTXN_DTL_V')
       order by 1,2,4
    
    TABLE_NAME     INDEX_NAME          INDEX_TYPE          COLUMN_NAME     COLUMN_POSITION     COLUMN_EXPRESSION
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    GACC_DTL_V1     GACC_DTL_BATCH_ID_INDX     NORMAL               BATCH_ID          1     
    GACC_DTL_V1     GACC_DTL_V1_IDX          NORMAL               BATCH_ID          2     
    GACC_DTL_V1     GACC_DTL_V1_IDX          NORMAL               ID               1     
    GACC_DTL_V1     GACC_DTL_V1_IDX2     FUNCTION-BASED NORMAL     SYS_NC00101$          1     SUBSTR("ID",1,3)
    GACC_DTL_V1     IDX_ACC1_V1          NORMAL               CATEGORY          1     
    GACC_DTL_V1     IDX_ACC3_V1          FUNCTION-BASED NORMAL     SYS_NC00099$          1     "CUSTOMER_NUMBER"||'.'||"LIMIT_REF"
    GACC_DTL_V1     IDX_ACC4_V1          FUNCTION-BASED NORMAL     SYS_NC00100$          1     "CUSTOMER_NUMBER"||'.000'||"LIMIT_REF"
    GACC_DTL_V1     IDX_ACC5_V1          NORMAL               POSTING_RESTRICT     1     
    GACC_DTL_V1     IDX_CUS5_V1          NORMAL               CUSTOMER_NUMBER          1     
    GACC_DTL_V1     IDX_CUS6_V1          NORMAL               LIMIT_REF          1     
    GCUS_DTL_V1     GCUS_DTL_V1_IDX1     NORMAL               CUSTOMER_NUMBER          1     
    GCUS_DTL_V1     IDX_CUS2_V1          NORMAL               BATCH_ID          1     
    GCUS_DTL_V1     IDX_CUS3_V1          NORMAL               BATCH_ID          1     
    GCUS_DTL_V1     IDX_CUS3_V1          NORMAL               CUSTOMER_NUMBER          2     
    GCUS_DTL_V1     IDX_CUS3_V1          NORMAL               INDUSTRY          4     
    GCUS_DTL_V1     IDX_CUS3_V1          NORMAL               SECTOR               3     
    GCUS_DTL_V1     IDX_CUS4_V1          FUNCTION-BASED NORMAL     SYS_NC00078$          1     SUBSTR("DATE_STAMP",1,6)
    We are also do not understand why the filter (SUBSTR ("TXN". ""»(, 1, 3) ACCOUNT_NUMBER = SUBSTR ("VAC". " ID", 1, 3)) is used in both queries.

    All tables are analyzed today.

    Please share your thoughts on this.

    Thanks in advance,
    Jac

    Jac says:

    L     H     NUM_BUCKETS     LAST_ANALYZED     SAMPLE_SIZE     HISTOGRAM
    ------------------------------------------------------------------------------------------------------------------------------------------------
    010109     311208     235     13/Jun/2009     5,343     FREQUENCY
    

    You have a histogram of frequencies on the BATCH_ID column missing at least 2 values according to your index statistics (235 buckets vs 237 separate keys).

    If the value that you use in the query is missing then this could be the explanation for the estimation of cardinality bad (since you're on pre - 10.2.0.4. In 10.2.0.4 that this behavior changes).

    The size of the sample of 5 300 lines is also very low, given the 57,000,000 lines according to the index statistics.

    You have two options (which can be combined):

    -Increase the size of the sample using a parameter explicitly estimate_percent, for example at least 10 percent

    exec DBMS_STATS. GATHER_TABLE_STATS (null, 'GACC_DTL_V1', estimate_percent-online 10, method_opt => 'FOR COLUMNS SIZE 254 BATCH_ID,' waterfall-online fake)

    -Get rid of the histogram

    exec DBMS_STATS. GATHER_TABLE_STATS (null, 'GACC_DTL_V1', method_opt-online 'FOR BATCH_ID COLUMNS SIZE 1', cascade-online fake)

    Note: Is there a particular reason why you store numbers in varchar columns? This might be the reason why Oracle believes that it must generate a histogram using the AUTO SIZE option.

    I tend to promote to remove from the histogram, but you must first verify the data if the BATCH_ID values are spread out and the histogram is reasonable:

    select
            batch_id
          , count(*)
    from
            gacc_dtl_v1
    group by
            batch_id;
    

    No constarints are at the DB level. All are processed Application level.

    Have you checked this in DBA/ALL/USER_CONSTRAINTS?

    It's also a good idea to have constraints at the level of the DB. It keeps your data consistent and quite often helps the optimizer. It allows even 10.2 and later to make things like the elimination of a join table that can make a huge difference in performance.

    Kind regards
    Randolf

    Oracle related blog stuff:
    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/

    Published by: Randolf Geist on June 16, 2009 11:48

    Comment added constraints

  • Question about cardinality (lines) to explain the plan

    I have two tables (names have been changed to protect the innocent):


    TABLE 1:


    The Null columns?    Type

    -------------------- -------- ----------------------------------------------

    Table1_Primary_Key NOT NULL NUMBER

    more than 10 columns


    TABLE2:


    The Null columns?    Type

    -------------------- -------- ----------------------------------------------

    Table2_Primary_Key NOT NULL NUMBER

    more than 8 columns


    Lines of table1 has 1097172


    Rows of table2 has 160960


    I am analysis request and get explain below:


    SELECT t1. Table1_Primary_Key

    --

    FROM TABLE1 t1,

    From TABLE2 T2

    --

    WHERE t1. Table1_Primary_Key = t1. Table1_Primary_Key

    AND t2. Table2_Primary_Key = 3432798

    /


    ------------------------------------------------------------------------------------------------

    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

    ------------------------------------------------------------------------------------------------

    |   0 | SELECT STATEMENT |                 |     1.    21.     5 (0) | 00:00:01 |

    |   1.  NESTED LOOPS |                 |     1.    21.     5 (0) | 00:00:01 |

    |   2.   TABLE ACCESS BY INDEX ROWID | TABLE2.     1.    12.     3 (0) | 00:00:01 |

    |*  3 |    INDEX UNIQUE SCAN | TABLE2_PK |     1.       |     2 (0) | 00:00:01 |

    |   4.   TABLE ACCESS BY INDEX ROWID | TABLE1.  1096K |  9634K |     2 (0) | 00:00:01 |

    |*  5 |    INDEX UNIQUE SCAN | TABLE1_PK |     1.       |     1 (0) | 00:00:01 |

    ------------------------------------------------------------------------------------------------


    As you can see it table2 is exactly 1 row and join table1 on a correspondence of single line.


    My question is this:


    Why the plan of the explain command seems (at least for me) to indicate that it looked like all the rows in TABLE1?


    Thank you


    Thomas

    the optimizer's decisions are based on the object (and maybe system) statistics: so it's a good idea to provide as much information as possible in these statistics. Basically, there is nothing wrong with statistics automatic collection job - so I would count on that if I don't have very good reason to use anything else. Of course, there are some situations in which it's a good idea to add a few adjustions for automatic collection: sometimes, there is too much created histograms, sometimes there is too little (basically you have histograms when the distribution of the data is not yet). And if there are columns with correlated values who serve together in boundary conditions then create extensive statistics may be a good idea. To make these adjustions, you can use the routines of pref dbms_stats. And sometimes, it may even be a good idea is not to collect statistics for an object and use the sample dynamic (dynamic statistics) for more detailed information on the cardinality of distribution and join.

    In the book of my opinion Jonathan Lewis cost base Oracle Fundamentals still contains the best explanation of the use of optimizer statistics - and Christian Antognini Oracle performance troubleshooting also provides a lot of valuable information about statistics and their gathering. Of course the documentation also explains the basics in detail: Managing optimizer statistics - 11 g Release 2 (11.2). And if you want to get a shorter summary, then you can always take a look at the Web of Tim Hall site: https://oracle-base.com/articles/misc/cost-based-optimizer-and-database-statistics.

  • why sometimes the trace file does not explain the plan?

    Hello

    Sometimes, when I 'alter session set sql_trace = true' and run some querys, some of them don't see explained the plan in the trace file?

    I tried "alter system RAS shared_pool" before starting the trace, but not luck.

    (Oracle 10g R2)

    any ideas?

    Thnks
    Miguel

    Published by: jmmnunes on Apr 27, 2010 18:01

    some of them don't watch not explain the plan in the trace file?

    Log out of your session after you set the trace sql false?

    All cursors must be closed to have access to all the information from the row source in the trace file.

  • explain the plan of a query with variables

    Trying to Explain plan at some sql code in sql * more. The query has a variable. How can I do this?

    I look to explain the plan and dbms_xplan but did not find anything with variables

    use sqlplus variable bind:

    SQL> --define variable
    SQL> var x varchar2
    
    SQL> -- notice the colon prefixing the variable
    SQL> explain plan for select * from customer where cid = :x;
    
    Explained.
    
    SQL> select * from table( dbms_xplan.display );
    
    PLAN_TABLE_OUTPUT
    -----------------------------------------------------------------------------------------------
    Plan hash value: 1709312366
    
    ----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |          |     1 |    67 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| CUSTOMER |     1 |    67 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | CID      |     1 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("CID"=:X)
    
    14 rows selected.
    

    the variable should not be set to explain the request, because explain does not actually run.

    Published by: shoblock on November 6, 2008 16:51

  • Explain the explain plan

    decide to move to optimization soon. Book says join faster that the subquery in this example because the analyses involved. The "cost" to the subquery appears lower than the cost for the join. So it is confusing to me - aka How should I be interpreting this.

    Plan of subquery:

    image2.png.jpg

    join plan

    image2.png.jpg

    as you can see that the plan for the subquery has less than a cost. Could someone explain these outputs as to which application is more effective. I need to start somewhere.

    Thank you!

    The BEST way to get help when you ask questions is:

    1 ask questions on SPECIFIC things

    2. tell us EXACTLY what term, value, etc. ask abaout

    Book says join faster that the subquery in this example because the analyses involved. The "cost" to the subquery appears lower than the cost for the join. So it is confusing to me - aka How should I be interpreting this.

    OK - what BOOK are you talking about? There is not much interest to mention a book if you're not going to tell us which book it and provide a link to it and even a page number. This gives us the SCOPE of your question.

    This "cost for the subquery" are you talking about? Be specifc. It is in one of the plans that you posted? What plan? Whose cost is it? For example, you could say:

    I have a question for the foreground below. Why is the cost to the xx line lower than the cost of the second plan on line AA?

    This question refers CLEARLY to the info we're talking. The way in which you stating the question, we try to guess what plan and the lines you want to say.

    subquery plan:
    
    
    join plan
    
    
    as you can see the subquery plan has less of a cost. Could someone explain from these outputs as to which query is more efficient. I need to start from somewhere.
    

    Are you talking about line #1 in each of these plans?

    Please edit your post and tell us EXACTLY what you ask in the topic and refer to values and SPECIFIC lines. Also post a link to the book and a reference to a page number you got the information from.

    The optimizer generally chooses the REAL implementation with the lowest cost plan. It is not clear whether the plans that you have posted are ACTUAL spending plans that Oracle really determined and used or just explain plans.for what Oracle thought it might use.

    If the statistics are not up-to-date these plans do not yet reflect the reality of the data.

    And if the amount of data is a small number of blocks or other of these plans can run better than the other in reality.

    You can find this Oracle white paper "Explain the Plan explaining" useful

    http://www.Oracle.com/technetwork/database/bi-Datawarehousing/TWP-explain-the-explain-plan-052011-393674.PDF

Maybe you are looking for

  • Videos YouTube won't play.

    I have Firefox 18. I have the last Flash from Adobe installed (after you do a complete uninstall and reinstall). I cleared the cache, cookies, etc. No matter what I try, videos YouTube won't play in Firefox. I always get the same message: "An error h

  • change the size of array without initializing

    Hello I'm trying to dynamically change the table size. I'm doing a calibration of an instrument and from time to time I read 3 parameters and try to write in an empty array (do not reset) and caclulate interpolation polinom according to my measured d

  • you will get a virus if you sign up for maplestory?

    you will get a virus if you sign up for maplestory?

  • Mouse HP Z5000

    On my nice DELL Lattitude E7240 new with windows 7 my bluetooth HP Z5000 company newly purchased works beautifully for 30 seconds and then freezes. Why?

  • Problem send and receive e-mail with Windows Mail

    For two days, my Windows Mail service ceased to send or receive e-mail addresses. My internet service provider is Comcast. A Comcast tech checked the problem and determined that the problem is with Windows Mail and not Comcast. Any ideas on how to ge