English 中文(简体)
甲状腺 9i - Date酸 Date的优化问题
原标题:Oracle 9i - Optimizer Issues with Date Arithmetic?

我们有一个问题,包括(但还有其他加入、表格和条件):

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    ? <= o.submitted_date
    AND o.submitted_date < ? + 1

called诉。

<代码>? paramaters允许核对两个日期之间的订单。

然而,这种询问进展缓慢。

我们从PL/SQL转来测试如下:

SubmittedDateFrom date:=to_date( 2011-07-15 ,  yyyy-mm-dd );
SubmittedDateTo date:=to_date( 2011-07-15 ,  yyyy-mm-dd );
CURSOR c_orgs    IS    
SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o
WHERE   
    SubmittedDateFrom <= o.submitted_date
    AND o.submitted_date < SubmittedDateTo + 1;
BEGIN
    FOR c_o IN c_orgs LOOP
        DBMS_OUTPUT.put_line( Submitted date =  ||c_o.submitted_date);                               
    END LOOP;
END;

IF we either:

  1. convert the SubmittedDateTo value to to_date( 2011-07-16 , yyyy-mm-dd ) (i.e. do the arithmetic outside the query),
  2. make SubmittedDateTo a string and use "to_date( SubmittedDateTo , yyyy-mm-dd ) + 1" as the second condition in the WHERE.

THEN, the query speeds up dramatically ( < 1 second vs. 44+ seconds).

Further information:

  • running an explain plan on the query gives the error ORA-00932: inconsistent datatypes: expected DATE got NUMBER
  • the submitted_date column has an index and stats, etc. have been run
  • wrapping the SubmittedDateTo + 1 in a trunc() call does not affect performance
  • We do not have a non-9i database with similar data volumes, etc. to test if it s the version of Oracle or not.

The question is: we are unable to find any information which clearly states that the Oracle 9i Optimizer has an issue with this kind of date arithmetic. Is that what s happening here or is there something else going on?

最佳回答

I d always ensure that all conversions are handled explicitly (and assuming o.submitted_date is a DATE datatype):

DECLARE
  CURSOR c_orgs    
  IS
     SELECT o.contact_id,      
            o.completed_date,
            o.submitted_date 
       FROM orders o 
      WHERE o.submitted_date BETWEEN TO_DATE(SubmittedDateFrom,  yyyy-mm-dd ) 
                                 AND TO_DATE(SubmittedDateTo,  yyyy-mm-dd ); 
BEGIN
   FOR c_o IN c_orgs 
   LOOP
      DBMS_OUTPUT.put_line( Submitted date =  ||c_o.submitted_date);
   END LOOP;
END; 

This ensures there is no errors in any implicit conversions and all conversions are obvious in their data type.

“问题是:我们无法找到任何明确表明Oracle 9i Bestizer有这种计算日期的问题的信息。 这里发生的情况,还是还有什么事情发生?

I don t think it is the optimiser, it could be the end product of your implicit conversions are causing the performance issues. As we do not have you NLS settings for dates etc from the Oracle database it d be hard to tell but if using explicit conversions increases performance, then I d suggest you use them (and it s better pracitce too).

希望会帮助Olie。

问题回答

http://download.oracle.com/docs/cd/B13789_01/server.101/b10752/ex_plan.htm 甲型六氯环己烷 (第10条),但我猜测这也适用于9i,“......不支持EXPLAIN PLAN, 用于进行日期约束变数的默示类型转换的声明”。

Apart from the approach sugggested by Ollie, have you tried using trunc() resp. between instead?

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    trunc(o.submitted_date) = trunc(?)

resp.

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    o.submitted_date between ? and ? + 1




相关问题
Export tables from SQL Server to be imported to Oracle 10g

I m trying to export some tables from SQL Server 2005 and then create those tables and populate them in Oracle. I have about 10 tables, varying from 4 columns up to 25. I m not using any constraints/...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

How to make a one to one left outer join?

I was wondering, is there a way to make a kind of one to one left outer join: I need a join that matches say table A with table B, for each record on table A it must search for its pair on table B, ...

Insert if not exists Oracle

I need to be able to run an Oracle query which goes to insert a number of rows, but it also checks to see if a primary key exists and if it does, then it skips that insert. Something like: INSERT ALL ...

How can I store NULLs in NOT NULL field?

I just came across NULL values in NOT-NULL fields in our test database. How could they get there? I know that NOT-NULL constraints can be altered with NOVALIDATE clause, but that would change table s ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

热门标签