Simple query optimization

Hi,
I'm using Oracle 10g r2.
I have this simple query that seems to take too much time to execute :
DECLARE
     nb_mesures INTEGER;
     min_day DATE;
     max_day DATE;
BEGIN
     SELECT
          COUNT(meas_id),
          MIN(meas_day),
          MAX(meas_day)
     INTO
          nb_mesures,
          min_day,
          max_day
     FROM
          geodetic_measurements gm
          INNER JOIN
          operation_measurements om
          ON gm.meas_id = om.ogm_meas_id
     WHERE ogm_op_id = 0;
     htp.p(nb_mesures||' measurements from '||min_day||' to '||max_day);
END;- Tables (about 11.000 records for the "Operations" table, and 800.000 for the 2 others) :
"Operation_measurements" is the table who makes the link between the 2 others (get the 2 keys).
SQL> DESCRIBE OPERATIONS
Nom                  NULL     Type
OP_ID                NOT NULL NUMBER(7)
OP_PARENT_OP_ID               NUMBER(7)
OP_RESPONSIBLE       NOT NULL VARCHAR2(10)
OP_DESCRIPT                   VARCHAR2(80)
OP_VEDA_NAME         NOT NULL VARCHAR2(10)
OP_BEGIN             NOT NULL DATE
OP_END                        DATE
OP_INSERT_DATE                DATE
OP_LAST_UPDATE                DATE
OP_INSERT_BY                  VARCHAR2(50)
OP_UPDATE_BY                  VARCHAR2(50)
SQL> DESCRIBE OPERATION_MEASUREMENTS
Nom                  NULL     Type
OGM_MEAS_ID          NOT NULL NUMBER(7)
OGM_OP_ID            NOT NULL NUMBER(6)
OGM_INSERT_DATE               DATE
OGM_LAST_UPDATE               DATE
OGM_INSERT_BY                 VARCHAR2(50)
OGM_UPDATE_BY                 VARCHAR2(50)
SQL> DESCRIBE GEODETIC_MEASUREMENTS
Nom                  NULL     Type
MEAS_ID              NOT NULL NUMBER(7)
MEAS_TYPE            NOT NULL VARCHAR2(2)
MEAS_TEAM            NOT NULL VARCHAR2(10)
MEAS_DAY             NOT NULL DATE
MEAS_OBJ_ID          NOT NULL NUMBER(6)
MEAS_STATUS                   VARCHAR2(1)
MEAS_COMMENT                  VARCHAR2(150)
MEAS_DIRECTION                VARCHAR2(1)
MEAS_DIST_MODE                VARCHAR2(2)
MEAS_SPAT_ID         NOT NULL NUMBER(7)
MEAS_INST_ID                  NUMBER(7)
MEAS_DECALAGE                 NUMBER(8,5)
MEAS_INST_HEIGHT              NUMBER(8,5)
MEAS_READING         NOT NULL NUMBER(11,5)
MEAS_CORRECT_READING          NUMBER(11,5)
MEAS_HUMID_TEMP               NUMBER(4,1)
MEAS_DRY_TEMP                 NUMBER(4,1)
MEAS_PRESSURE                 NUMBER(4)
MEAS_HUMIDITY                 NUMBER(2)
MEAS_CONSTANT                 NUMBER(8,5)
MEAS_ROLE                     VARCHAR2(1)
MEAS_INSERT_DATE              DATE
MEAS_LAST_UPDATE              DATE
MEAS_INSERT_BY                VARCHAR2(50)
MEAS_UPDATE_BY                VARCHAR2(50)
MEAS_TILT_MODE                VARCHAR2(4000) - Explain plan (I'm not familiar with explain plans...) :
| Id  | Operation                     | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
PLAN_TABLE_OUTPUT
|   0 | SELECT STATEMENT              |                        |     1 |    19 |   256  (10)| 00:00:02 |
|   1 |  SORT AGGREGATE               |                        |     1 |    19 |            |          |
|   2 |   NESTED LOOPS                |                        |    75 |  1425 |   256  (10)| 00:00:02 |
|*  3 |    TABLE ACCESS FULL          | OPERATION_MEASUREMENTS |    75 |   600 |    90  (27)| 00:00:01 |
|   4 |    TABLE ACCESS BY INDEX ROWID| GEODETIC_MEASUREMENTS  |     1 |    11 |     3   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN         | MEAS_PK_2              |     1 |       |     2  (50)| 00:00:01 |
--------------------------------------------------------------------------------------------------------How can I optimize this query ?
Thanks.
Yann.

Looks like you are missing an FK-index on the middle table, for the FK going to OPERATIONS.
Currently this:
WHERE ogm_op_id = 0;Is computed via a full table scan followed by a filter operation. Assuming OP_ID is rather selective, an index on OGM_OP_ID could do the trick here.

Similar Messages

  • Trying to optimize this simple query

    Hi,
    I am trying to optimize this simple query but the two methods I am trying actually make things worse.
    The original query is:
    SELECT customer_number, customer_name
    FROM bsc_pdt_account_mv
    where rownum <= 100
    AND Upper(customer_name) like '%SP%'
    AND customer_id IN
    SELECT cust_id FROM bsc_pdt_assoc_sales_force_mv
    WHERE area_identifier IN (
    SELECT area_identifier FROM bsc_pdt_assoc_sales_force_mv
    WHERE ad_identifier = '90004918' or rm_identifier = '90004918' or tm_identifier = '90004918'
    The result set of this query returns me the first 100 rows in 88 seconds and they are all distinct by default (don't know why they are distinct).
    My first attempt was to try to use table joins instead of the IN conditions:
    SELECT
    distinct -- A: I need to use distinct now
    customer_number, customer_name
    FROM bsc_pdt_account_mv pdt,
    bsc_pdt_assoc_sales_force_mv asf,
    SELECT distinct area_identifier FROM bsc_pdt_assoc_sales_force_mv
    WHERE ad_identifier = '90004918' or rm_identifier = '90004918' or tm_identifier = '90004918'
    ) area
    where
    area.area_identifier = asf.area_identifier
    AND asf.cust_id = pdt.customer_id
    AND Upper(customer_name) like '%SP%'
    AND rownum <= 100 -- B: strange when I comment this out
    order by 1
    I dont understand two things with this query. First issue, I now need to put in the distinct because the result set is not distinct by default. Second issue (very strange), when I put the rownum condition (<100) I get two rows in 1.5 seconds. If I remove the condition, I get 354 rows (whole result set) in 326 seconds.
    My second attempt was to use EXISTS instead of IN:
    SELECT
    customer_number, customer_name
    FROM bsc_pdt_account_mv pdt
    where Upper(customer_name) like '%SP%'
    AND rownum <= 100
    AND EXISTS
    select 1 from
    bsc_pdt_assoc_sales_force_mv asf,
    SELECT distinct area_identifier FROM bsc_pdt_assoc_sales_force_mv
    WHERE ad_identifier = '90004918' or rm_identifier = '90004918' or tm_identifier = '90004918'
    ) area
    where
    area.area_identifier = asf.area_identifier
    AND asf.cust_id = pdt.customer_id
    This query returns a similar distinct result set as teh original one but takes pretty much the same time (87 seconds).

    The query below hangs when run in TOAD or PL/SQL Dev. I noticed there is no rows returned from the inner table for this condition.
    SELECT customer_number, customer_name
    FROM
    bsc_pdt_account_mv pdt_account
    where rownum <= 100
    AND exists (
    SELECT pdt_sales_force.cust_id
    FROM bsc_pdt_assoc_sales_force_mv pdt_sales_force
    WHERE pdt_account.customer_id = pdt_sales_force.cust_id
    AND (pdt_sales_force.rm_identifier = '90007761' or pdt_sales_force.tm_identifier = '90007761') )
    ORDER BY customer_name
    -- No rows returned by this query
    SELECT pdt_sales_force.cust_id
    FROM bsc_pdt_assoc_sales_force_mv pdt_sales_force
    WHERE pdt_sales_force.rm_identifier = '90007761' or pdt_sales_force.tm_identifier = '90007761'

  • Simple query takes time to run

    Hi,
    I have a simple query whcih takes about 20 mins to run.. here is the TKPROF forit:
      SELECT
        SY2.QBAC0,
        sum(decode(SALES_ORDER.SDCRCD,'USD', SALES_ORDER.SDAEXP,'CAD', SALES_ORDER.SDAEXP /1.0452))
      FROM
        JDE.F5542SY2  SY2,
        JDE.F42119  SALES_ORDER,
        JDE.F0116  SHIP_TO,
        JDE.F5542SY1  SY1,
       JDE.F4101  PRODUCT_INFO
    WHERE
        ( SHIP_TO.ALAN8=SALES_ORDER.SDSHAN  )
        AND  ( SY1.QANRAC=SY2.QBNRAC and SY1.QAOTCD=SY2.QBOTCD  )
        AND  ( PRODUCT_INFO.IMITM=SALES_ORDER.SDITM  )
        AND  ( SY2.QBSHAN=SALES_ORDER.SDSHAN  )
        AND  ( SALES_ORDER.SDLNTY NOT IN ('H ','HC','I ')  )
        AND  ( PRODUCT_INFO.IMSRP1 Not In ('   ','000','689')  )
        AND  ( SALES_ORDER.SDDCTO IN  ('CO','CR','SA','SF','SG','SP','SM','SO','SL','SR')  )
        AND  (
        ( SY1.QACTR=SHIP_TO.ALCTR  )
        AND  ( PRODUCT_INFO.IMSRP1=SY1.QASRP1  )
      GROUP BY
      SY2.QBAC0
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.07       0.07          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch       10     92.40     929.16     798689     838484          0         131
    total       12     92.48     929.24     798689     838484          0         131
    Misses in library cache during parse: 1
    Optimizer goal: CHOOSE
    Parsing user id: 62 
    Rows     Row Source Operation
        131  SORT GROUP BY
    3535506   HASH JOIN 
    4026100    HASH JOIN 
        922     TABLE ACCESS FULL OBJ#(187309)
    3454198     HASH JOIN 
      80065      INDEX FAST FULL SCAN OBJ#(30492) (object id 30492)
    3489670      HASH JOIN 
      65192       INDEX FAST FULL SCAN OBJ#(30457) (object id 30457)
    3489936       PARTITION RANGE ALL PARTITION: 1 9
    3489936        TABLE ACCESS FULL OBJ#(30530) PARTITION: 1 9
      97152    TABLE ACCESS FULL OBJ#(187308)
    OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.07       0.07          0          0          0           0
    Execute      2      0.00       0.00          0          0          0           0
    Fetch       10     92.40     929.16     798689     838484          0         131
    total       13     92.48     929.24     798689     838484          0         131
    Misses in library cache during parse: 1kindly suggest how to resolve this...
    OS is windows and its 9i DB...
    Thanks

    > ... you want to get rid of the IN statements.
    They prevent Oracle from usering the index.
    SQL> create table mytable (id,num,description)
      2  as
      3   select level
      4        , case level
      5          when 0 then 0
      6          when 1 then 1
      7          else 2
      8          end
      9        , 'description ' || to_char(level)
    10     from dual
    11  connect by level <= 10000
    12  /
    Table created.
    SQL> create index i1 on mytable(num)
      2  /
    Index created.
    SQL> exec dbms_stats.gather_table_stats(user,'mytable')
    PL/SQL procedure successfully completed.
    SQL> set autotrace on explain
    SQL> select id
      2       , num
      3       , description
      4    from mytable
      5   where num in (0,1)
      6  /
                                        ID                                    NUM DESCRIPTION
                                         1                                      1 description 1
    1 row selected.
    Execution Plan
    Plan hash value: 2172953059
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |         |  5001 |   112K|     2   (0)| 00:00:01 |
    |   1 |  INLIST ITERATOR             |         |       |       |            |          |
    |   2 |   TABLE ACCESS BY INDEX ROWID| MYTABLE |  5001 |   112K|     2   (0)| 00:00:01 |
    |*  3 |    INDEX RANGE SCAN | I1      |  5001 |       |     1   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - access("NUM"=0 OR "NUM"=1)Regards,
    Rob.

  • SQL query optimization... Any idea?

    Hi all.
    Our DB (Oracle 9i RAC) is handling the prepaid service of a GSM mobile operator.
    We're having a query running every night to list the used vouchers from a table containing the vouchers data.
    Here is the query:
    select ticketno||' '||serialid||' '||used||' '||vouchervalue||' '||usedby from smv_avoucher where state='2' and trunc(used)=trunc(sysdate-1);
    As you can see we scan the entire table for used vouchers (state='2') for the previous day (sysdate-1). The 'used' column contains the date the voucher was used.
    Can this query be optimized? How can you improve this very simple query, or make it nicer for the DB?
    The reason we are trying to optimize this query is that it takes a long time to execute and generates "snapshot too old" error messages. We could use a large rollback segment for it, but first we would like to find out if the query can be optimized or not.
    Thank you for your insights.

    Thank you for your answers.
    What is the execution plan of this query? Can you post it?
    Operation                      Object
    SELECT STATEMENT ()
    TABLE ACCESS (FULL)           SMV_AVOUCHER
    How many records this table contains?About 25 million records
    Do you have any indexes on smv_avoucher?Yes we do have several indexes but not on 'used'
    Also you have to make sure you have most current statistics collected.Sorry would you mind to clarify this? I am not sure I understand fully.
    It seems to me that this query does full table scan, since you use trunc(used) (unless you have Function Based Index on trunc(used)).It does indeed.
    If you have index on used, it won't be used since you use function against the column. Oracle would use full table scan instead. I get it. Thanks for this information.
    I assume this table is and the data is frequently changed. These circumstances may lead to "snapshot too old".The table is updated very frequently (subscribers use vouchers to recharge their prepaid phones and new vouchers are provisioned into the DB all the time). This is a 5 million subscribers network.
    My initial suggestion would be to get rid of trunc(used)=trunc(sysdate-1) and to replace it with something like used between trunc(sysdate-1) and trunc(sysdate).Of course you have to have index on used.
    I will create this index and try this again.
    About column state ... How many distinct values it has?5 distinct values only.
    Might be a good candidate for IOTUnfortunately we are not at liberty to make such changes. Thanks for the suggestion though.
    Regards

  • How to write a simple query.

    I have a table where I have data shown below. Now, I want to write a simple query which lists me the project and the count of the distinct effective dates for which data is existant there.
    Sample data:
    Project Task Effective Date (xx_proj_task_data)
    101 T1 01-Jan-2008
    101 T1 01-Feb-2008
    101 T1 01-Mar-2008
    101 T2 01-Jan-2008
    101 T2 01-Apr-2008
    101 T3 01-Apr-2008
    102 T1 01-Jan-2008
    102 T1 01-Feb-2008
    102 T2 01-Apr-2008
    103 T1 01-Jan-2008
    103 T1 01-Feb-2008
    103 T1 01-Mar-2008
    103 T1 01-Apr-2008
    103 T2 01-May-2008
    103 T3 01-Jun-2008
    103 T1 01-Jan-2008
    103 T1 01-Aug-2008
    103 T2 01-Apr-2008
    Output Reqd:
    Project Count(Distinct Effective Dates)
    101 4
    102 3
    103 7
    I can write a query that says:
    select project_id, count(1)
    from (select distinct project_id, effective_date
    from xx_proj_task_data) x
    group by project_id;
    But, is there a way I can achieve the same by avoiding the inner Query (x) and just by a simple query ?
    Thanks!

    Try below query:
    select project_id
    , count(distinct effective_date)
    from xx_proj_task_data
    group by project_id;
    --venkata                                                                                                                                                                                                                                                                                       

  • Simple Query in Oracle Linked Table in MS Access causes full table scan.

    I am running a very simple query in MS ACCESS to a linked Oracle table as follows:
    Select *
    From EXPRESS_SERVICE_EVENTS --(the linked table name refers to EXPRESS.SERVICE_EVENTS)
    Where performed > MyDate()
    or
    Select *
    From EXPRESS_SERVICE_EVENTS --(the linked table name refers to EXPRESS.SERVICE_EVENTS)
    Where performed > [Forms]![MyForm]![Date1]
    We have over 50 machines and this query runs fine on over half of these, using an Oracle Index on the "performed" field. Running exactly the same thing on the other machines causes a full table scan, therefore ignoring the Index (all machines access the same Access DB).
    Strangely, if we write the query as follows:
    Select *
    From EXPRESS_SERVICE_EVENTS
    Where performed > #09/04/2009 08:00#
    it works fast everywhere!
    Any help on this 'phenominon' would be appreciated.
    Things we've done:
    Checked regional settings, ODBC driver settings, MS Access settings (as in Tools->Options), we have the latest XP and Office service packs, and re-linked all Access Tables on both the slow and fast machines independantly).

    Primarily, thanks gdarling for your reply. This solved our problem.
    Just a small note to those who may be using this thread.
    Although this might not be the reason, my PC had Oracle 9iR2 installed with Administratiev Tools, where user machines had the same thing installed but using Runtime Installation. For some reason, my PC did not have 'bind date' etc. as an option in the workarounds, but user machines did have this workaround option. Strangely, although I did not have the option, my (ODBC) query was running as expected, but user queries were not.
    When we set the workaround checkbox accordingly, the queries then run as expected (fast).
    Once again,
    Thanks

  • Oracle 11g on Linux : Query Optimization issue

    Hi guru,
    I am facing one query optimization related problem in group by query
    Table (10 million Records)
    Product(ProductId number,ProductName varchar(100),CategoryId VARCHAR2(38),SubCategoryId VARCHAR2(38))
    Index
    create index idxCategory on Product (CategoryId,SubCategoryId)
    Query1:To find product count for all CategoryId and SubCategoryId
    select CategoryId,SubCategoryId,count(*) from Product group by CategoryId,SubCategoryId
    Above query is not using index idxCategory and doing table scan which is very costly.
    When I fire Query2: select count(*) from Product group by CategoryId,SubCategoryId
    then it is properly using index idxCategory and very fast.
    Even I specified hint in Query1 but it is not using hint.
    Can anybody suggest why oracle is not using index in Query1 and what should I do so that Query1 will use Index.
    Thanks in advance.

    user644199 wrote:
    I am facing one query optimization related problem in group by query
    Query1:To find product count for all CategoryId and SubCategoryId
    select CategoryId,SubCategoryId,count(*) from Product group by CategoryId,SubCategoryId
    Above query is not using index idxCategory and doing table scan which is very costly.
    When I fire Query2: select count(*) from Product group by CategoryId,SubCategoryId
    then it is properly using index idxCategory and very fast.
    Even I specified hint in Query1 but it is not using hint.
    Can anybody suggest why oracle is not using index in Query1 and what should I do so that Query1 will use Index.The most obvious reason that the table needs to be visited would be that the columns "CategoryId" / "SubCategoryId" can be NULL but then this should apply to both queries. You could try the following to check the NULL issue:
    select CategoryId,SubCategoryId,count(*) from Product where CategoryId is not null and SubCategoryId is not null group by CategoryId,SubCategoryId
    Does this query use the index?
    Can you show us the hint you've used to force the index usage and the EXPLAIN PLAN output of the two queries including the "Predicate Information" section? Use DBMS_XPLAN.DISPLAY to get a proper output, and use the \ tag before and after when posting here to format it using fixed font. Use the "Quote" button in the message editor to see how I used the \ tag here.
    Are above queries representing the actual queries used or did you omit some predicates etc. for simplicity?
    By the way, VARCHAR2(38) and ...ID as name, are these columns storing number values?
    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/

  • Error in the simple Query

    Dear Experts,
    Not able to Execute this simple query :
    Select T1.JobID , T1.BudgetValue,T1.ActualValue FROM [dbo].[Enprise_JobCost_ActualBudgetView] T1 WHERE T1.TransType = '[%0]'
    Regards

    Hello,
    View - A View in simple terms is a subset of a 'virtual table. It can be used to retrieve data from the tables, Insert, Update or Delete from the tables. The Results of using View are not permanently  stored in the database.
    Stored Procedure -  A stored procedure is a group of SQL statements which can be stored into the database and can be shared over the netwrok with different users.
    http://www.geekinterview.com/question_details/65914
    Better make a UDT for your requirement.
    Thanks
    Manvendra Singh Niranjan

  • What is query optimization and how to do it.

    Hi
    What is query optimization?
    Any link can any one provide me so that i can read and learn the techniques.
    Thanks
    Elias Maliackal

    THis is an excellent place to start: When your query takes too long ...

  • Simple Query working on 10G and not working on 11gR2 after upgrade

    Hi Folks,
    This is the first time i am posting the query in this Blog.
    I have a small issue which preventing the UAT Sigoff.
    Simple query working fine on 10.2.0.1 and after upgrade to 11.2.0.1 its error out
    10.2.0.4:
    =====
    SQL> SELECT COUNT(*) FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1=1;
    COUNT(*)
    1
    SQL> SELECT COUNT(*) FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1=00001;
    COUNT(*)
    1
    SQL> select ATTRIBUTE1 FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1=1;
    ATTRIBUTE1
    00001
    11.2.0.1:
    =====
    SQL> SELECT COUNT(*) FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1=1
    ERROR at line 1:
    ORA-01722: invalid number
    SQL> SELECT COUNT(*) FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1=00001
    ERROR at line 1:
    ORA-01722: invalid number
    SQL> select ATTRIBUTE1 FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1='1';
    no rows selected
    SQL> SELECT COUNT(*) FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1='00001';
    COUNT(*)
    1
    SQL> select ATTRIBUTE1 FROM APPS.HZ_PARTIES HP WHERE ATTRIBUTE_CATEGORY= 'PROPERTY' AND ATTRIBUTE1='00001';
    ATTRIBUTE1
    00001
    ++++++++++++++++++++++++++++++++++++++++++++++
    SQL > desc APPS.HZ_PARTIES
    Name Type
    ======== ======
    ATTRIBUTE1 VARCHAR2(150)
    ++++++++++++++++++++++++++++++++++++++++++++++
    Changes:
    Recently i upgraded the DB from 10.2.0.4 to 11.2.0.1
    Query:
    1.If the type of that row is VARCHAR,why it is working in 10.2.0.4 and why not working in 11.2.0.1
    2.after upgrade i analyzed the table with "analyze table " query for all AP,AR,GL,HR,BEN,APPS Schemas--Is it got impact if we run analyze table.
    Please provide me the answer for above two questions or refer the document is also well enough to understand.Based on the Answer client will sigoff to-day.
    Thanks,
    P Kumar

    WhiteHat wrote:
    the issue has already been identified: in oracle versions prior to 11, there was an implicit conversion of numbers to characters. your database has a character field which you are attempting to compare to a number.
    i.e. the string '000001' is not in any way equivalent to the number 1. but Oracle 10 converts '000001' to a number because you are asking it to compare to the number you have provided.
    version 11 doesn't do this anymore (and rightly so).
    the issue is with the bad code design. you can either: use characters in the predicate (where field = 'parameter') or you can do a conversion of the field prior to comparing (where to_num(field) = parameter).
    I would suggest that you should fix your code and don't assume that '000001' = 1I don't think that the above is completely correct, and a simple demonstration will show why. First, a simple table on Oracle Database 10.2.0.4:
    CREATE TABLE T1(C1 VARCHAR2(20));
    INSERT INTO T1 VALUES ('1');
    INSERT INTO T1 VALUES ('0001');
    COMMIT;A select from the above table, relying on implicit data type conversion:
    SELECT
    FROM
      T1
    WHERE
      C1=1;
    C1
    1
    0001Technically, the second row should not have been returned as an exact match. Why was it returned, let's take a look at the actual execution plan:
    SELECT
    FROM
      TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,NULL));
    SQL_ID  g6gvbpsgj1dvf, child number 0
    SELECT   * FROM   T1 WHERE   C1=1
    Plan hash value: 3617692013
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |      |       |       |     2 (100)|          |
    |*  1 |  TABLE ACCESS FULL| T1   |     2 |    24 |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter(TO_NUMBER("C1")=1)
    Note
       - dynamic sampling used for this statementNotice that the VARCHAR2 column was converted to a NUMBER, so if there was any data in that column that could not be converted to a number (or NULL), we should receive an error (unless the bad rows are already removed due to another predicate in the WHERE clause). For example:
    INSERT INTO T1 VALUES ('.0001.');
    SELECT
    FROM
      T1
    WHERE
      C1=1;
    SQL> SELECT
      2    *
      3  FROM
      4    T1
      5  WHERE
      6    C1=1;
    ERROR:
    ORA-01722: invalid numberNow the same test on Oracle Database 11.1.0.7:
    CREATE TABLE T1(C1 VARCHAR2(20));
    INSERT INTO T1 VALUES ('1');
    INSERT INTO T1 VALUES ('0001');
    COMMIT;
    SELECT
    FROM
      T1
    WHERE
      C1=1;
    C1
    1
    0001
    SELECT
    FROM
      TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,NULL));
    SQL_ID  g6gvbpsgj1dvf, child number 0
    SELECT   * FROM   T1 WHERE   C1=1
    Plan hash value: 3617692013
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |      |       |       |     2 (100)|          |
    |*  1 |  TABLE ACCESS FULL| T1   |     2 |    24 |     2   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter(TO_NUMBER("C1")=1)
    Note
       - dynamic sampling used for this statement
    INSERT INTO T1 VALUES ('.0001.');
    SELECT
    FROM
      T1
    WHERE
      C1=1;
    SQL> SELECT
      2    *
      3  FROM
      4    T1
      5  WHERE
      6    C1=1;
    ERROR:
    ORA-01722: invalid numberAs you can see, exactly the same actual execution plan, and the same end result.
    The OP needs to determine if non-numeric data now exists in the column. Was the database characterset possibly changed during/after the upgrade?
    Charles Hooper
    Co-author of "Expert Oracle Practices: Oracle Database Administration from the Oak Table"
    http://hoopercharles.wordpress.com/
    IT Manager/Oracle DBA
    K&M Machine-Fabricating, Inc.

  • Reg Query Optimization - doubts..

    Hi Experts,
    This is related to Blog by Mr Prakash Darji regarding "Query Optimization" posted on Jan 26 2006.In this to optimize query Generation of Report is suggested.
    I tried this, but I am not sure I am analyzing this correctly.
    I collected Stats data before and after Generation of Report.But how to be sure that this is helping me? Did any one has tried this?
    What to look for in Stats Data - duration?
    But duration would not be absolute parameter as there is factor of "Wait Time, User", so duration may depend on this.
    Please help me in this.
    Thanks
    Gaurav
    Message was edited by: Gaurav

    Any ideas Experts?

  • A simple query to show sales versus last year on daily basis/

    Hi guys,
    I want to build a simple query with day (1,2,3,4,5,6) on the rows and "sales current year" and "sales last year"
    on the columns.
    I have only 0CALDAY in my cube.
    How can I have on the rows the day in stead of the full date?
    I would like to see in the sames row sales current year and sales last year.
    Thanks
    Shlomi

    HI Shlomi
    Create a virtual characteristic in your infoprovider that can calculate the day from calendar Day. In ZXRSRZZZ while adding code for this virtual characteristic use the function module DATE_COMPUTE_DAY to compute the day for every calendar day.
    For calculating Sales Current year, create a restricted ky figure with Sales as the key figure. Add 0CalDay to this RKF and create a variable for this infoobject(Eg: ZCURYEAR) that will receive input from the user for the range of dates eg: 08/16/2009 - 08/22/2009.
    For Sales Prior year, create another restricted key figure with Sales. Add 0CalDay to this RKF and add a customer exit variable. In the Customer exit code use the ZCURYEAR variable and offset it to prior year in both the upper and lower limits. This should work.
    I hope this helps.
    Thanks.

  • A simple  query

    a simple query
    on plsql block
    if i don't define the size of a variable of number type what will be the default size ?
    declare
    a number ;
    begin
    null
    end;
    and in a procedure if i don't mention in or out in the parameters what will oracle take it by default ?
    create or replace procedure(a number,b number)
    is
    begin
    null
    end;
    PLs note that both the pl/sql blocks are just for giving an idea .
    regards
    SHUBH

    You can get such information from the documents.
    [imp]The absence of precision and scale designators specifies the maximum range and precision for an Oracle number.[imp]
    Cheers
    Sarma.

  • Improving a simple Query

    Following is a simple query, what i want to know, i have added upper select to get d.name which is the description of region_code. Can i get whole result with single select
    SELECT t.region_code,d.name, t.emp_contr
    FROM
    (SELECT c.br_region_fo_code as Region_Code,
    SUM(c.employer_contribution) AS emp_contr
    FROM core_business.cb_contr_emp_pmt_slip c
    GROUP BY c.br_region_fo_code ) t,
    general_information.cb_region_fo d
    WHERE t.br_region_fo_code = d.region_fo_code;

    Boneist wrote:
    malhi wrote:
    Following is a simple query, what i want to know, i have added upper select to get d.name which is the description of region_code. Can i get whole result with single select
    SELECT t.region_code,d.name, t.emp_contr
    FROM
    (SELECT c.br_region_fo_code as Region_Code,
    SUM(c.employer_contribution) AS emp_contr
    FROM core_business.cb_contr_emp_pmt_slip c
    GROUP BY c.br_region_fo_code ) t,
    general_information.cb_region_fo d
    WHERE t.br_region_fo_code = d.region_fo_code;To be honest, I wouldn't bother rewriting the above query - it looks like it's filtering early (although Oracle could choose to rewrite it so that it does the join first, I guess), so that you're reducing the number of rows that the outer query has to join to. That means less work. If it is rewriting, I'd stick a no_merge hint on the subquery, to tell Oracle to do the grouping first before joining.
    You could rewrite the above query as:
    SELECT c.br_region_fo_code AS region_code,
    d.name,
    SUM(c.employer_contribution) AS emp_contr
    FROM   core_business.cb_contr_emp_pmt_slip c,
    general_information.cb_region_fo d
    WHERE  t.br_region_fo_code = d.region_fo_code
    GROUP BY c.br_region_fo_code, d.name;but whether Oracle will filter early or not is another matter. You would have to test both runs.I believe that Jonathan Lewis had a demonstration of execution plans that showed Oracle transforming queries to "push" GROUP BY clause prior to a join when sufficient contraints were in place to allow that and there was a performance benefit in doing so. I'd certainly be interested in seeing whether this was being done. The optimisation was really aimed at reducing the size of the group by key columns.

  • Simple query takes 18 minutes to retrieve data....

    Hi,
    I am facing this problem at the customer site where a simple query on a table takes 18 minutes or more. Please find below the details.
    Table Structure
    CREATE TABLE dsp_data
    quantum_id NUMBER(11) NOT NULL,
    src      NUMBER(11) NOT NULL,
    call_status NUMBER(11) NOT NULL,
    dst NUMBER(11) NOT NULL,
    measurement_id NUMBER(11) NOT NULL,
    is_originating NUMBER(1)     NOT NULL,
    measurement_value NUMBER(15,4) NOT NULL,
    data_type_id NUMBER(3) NOT NULL,
    data VARCHAR2(200) NOT NULL
    TABLESPACE dsp_data_tspace
    STORAGE (PCTINCREASE 0 INITIAL 100K NEXT 1024K)
    PARTITION BY RANGE (quantum_id)
    (PARTITION dsp_data_default VALUES LESS THAN (100));
    CREATE INDEX dsp_data_idx ON dsp_data
    quantum_id,
    src,
         call_status,
    dst,
         measurement_id,
         is_originating,
    measurement_value,
    data_type_id
    TABLESPACE dsp_data_idx_tspace
    LOCAL;
    CREATE INDEX dsp_data_src_idx ON dsp_data
    src
    TABLESPACE dsp_data_idx_tspace
    LOCAL;
    CREATE INDEX dsp_data_dst_idx ON dsp_data
    dst
    TABLESPACE dsp_data_idx_tspace
    LOCAL;
    ALTER TABLE dsp_data
    ADD CONSTRAINT fk_dsp_data_1
    FOREIGN KEY
    quantum_id
    REFERENCES mds_measurement_intervals
    quantum_id
    ALTER TABLE dsp_data
    ADD CONSTRAINT fk_dsp_data_2
    FOREIGN KEY
    data_type_id
    REFERENCES mds_drilldown_types
    type_id
    ALTER TABLE dsp_data
    ADD CONSTRAINT pk_dsp_data
    PRIMARY KEY
    quantum_id,
    src,
    call_status,
    dst,
              measurement_id,
              is_originating,
    measurement_value,
    data_type_id,
    data
    USING INDEX
    TABLESPACE dsp_data_idx_tspace
    LOCAL;
    Table Space Creation
    All table space creation is done using following command
    CREATE TABLESPACE [tablespaceName]
    DATAFILE [tablespaceDatafile] SIZE 500M REUSE
    AUTOEXTEND ON NEXT 10240K
    DEFAULT STORAGE ( INITIAL 1024K
    NEXT 1024K
    MINEXTENTS 10
    MAXEXTENTS UNLIMITED
    PCTINCREASE 0
    Server Configuration on CUtsomer Site
    (1)     2 x Dual PA8900 Proc = 4GHz
    (2)     RAM = 16GB
    (3)     3 x Internal HDDs
    (4)     1 x External MSA-30 storage array (oracle db)
    Record Information On Customer Site
    select count(*) from dsp_data;
    COUNT(*)
    181931197
    select min (quantum_id) from dsp_data where dst=2;
    This takes 18 minutes or more....
    SQL> SQL> SQL> explain plan for select min (quantum_id) from dsp_data where dst=2;
    Explained.
    SQL> @?/rdbms/admin/utlxpls
    PLAN_TABLE_OUTPUT
    Plan hash value: 999040277
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
    | 0 | SELECT STATEMENT | | 1 | 14 | 1 (0)| 00:00:01 | | |
    | 1 | SORT AGGREGATE | | 1 | 14 | | | | |
    | 2 | FIRST ROW | | 92 | 1288 | 1 (0)| 00:00:01 | | |
    | 3 | PARTITION RANGE ALL | | 92 | 1288 | 1 (0)| 00:00:01 | 1 | 29 |
    |* 4 | INDEX FULL SCAN (MIN/MAX)| DSP_DATA_IDX | 92 | 1288 | 1 (0)| 00:00:01 | 1 | 29 |
    As mentioned above the query takes 18 minutes or more. This is a critical issue at customer. Can you please give your suggestions how to improve and reduce the query time. Thanks in advance.

    Hi,
    I did the following changes in the indexes of table.
    drop index DSP_DATA_IDX;
    create index DSP_DATA_MEASUREMENT_ID_IDX on DSP_DATA (MEASUREMENT_ID) TABLESPACE dsp_data_idx_tspace LOCAL;
    After that I did explain plan,
    explain plan for select min(QUANTUM_ID) from mds.DSP_DATA where SRC=11;
    PLAN_TABLE_OUTPUT
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU
    | 0 | SELECT STATEMENT | | 1 | 11 | 3 (0
    | 1 | SORT AGGREGATE | | 1 | 11 |
    | 2 | FIRST ROW | | 430K| 4626K| 3 (0
    | 3 | PARTITION RANGE ALL | | 430K| 4626K| 3 (0
    | 4 | INDEX FULL SCAN (MIN/MAX)| PK_DSP_DATA | 430K| 4626K| 3 (0
    Note
    - 'PLAN_TABLE' is old version
    14 rows selected
    SELECT table_name, index_name, monitoring, used FROM v$object_usage;
    TABLE_NAME INDEX_NAME MONITORING USED
    DSP_DATA DSP_DATA_SRC_IDX YES NO
    It seems that DSP_DATA_SRC_IDX is not getting used in query. What changes do i need to make so that DSP_DATA_SRC_IDX index gets used.
    Also, you have stated that to create global index on src and dst. How do i create them.
    Thanks in Advance.
    Edited by: 780707 on Jul 8, 2010 11:58 PM

Maybe you are looking for

  • Is there a way to run firefox at a higher frame rate for those with monitors capable of 120hz?

    I noticed that IE is smooth as silk when browsing websites compared to firefox. Is there an add-on or a setting I can change so that I can take advantage of my monitor which runs at 120hz?

  • How Do I Run the Apps?

    Hello all - have an HP Envy 4500, using the eprint centre, sched apps printing OK, but confused as to how to run the apps on demand. For example, HP Quick Forms. I can schedule, I can look at samples, but how does one print out a desired sheet such a

  • Adding a trademark symbol in xml flash menu

    Hi, I am a front end web designer/developer and analyst...struggling with putting an accordian flash xml menu together. I have it done except I need to add a simple trademark symbol circle with r. I am struggling with how to do this since I am not sa

  • Monitors adapters info needed

    I am switching from my old G4 to a new MacPro. On the G4, the kind of monitor connections (2) have like 30 pin holes (3 rows of 10) and some more on the side. The new MacPro only has a DVI port and a mini Display port. What kind of adapters do I need

  • One finger scrolling option for mouse is GONE from preferences?

    The one finger scrolling option for mouse is apparently GONE from the mouse system preferences? Why do they move/hide this stuff every other system update? Grrrrr! I turned off the one finger scrolling option in mouse preferences a while back before