Performance Oracle 9i-日期算法的优化器问题?

Performance Oracle 9i-日期算法的优化器问题?,performance,oracle,oracle9i,ora-00932,Performance,Oracle,Oracle9i,Ora 00932,我们有一个查询,其中包括(但有其他联接、表和where条件): 如果我们: 将SubmittedDateTo值转换为to_date('2011-07-16','yyyy-mm-dd')(即在查询之外执行算术) 将SubmittedDateTo设为字符串,并将“截止日期('SubmittedDateTo','yyyy-mm-dd')+1”用作中的第二个条件,其中 然后,查询速度显著加快(小于1秒,而大于44秒) 进一步资料: 对查询运行解释计划时会出现错误ORA-00932:不一致的数据类型:预

我们有一个查询,其中包括(但有其他联接、表和where条件):

如果我们:

  • SubmittedDateTo
    值转换为
    to_date('2011-07-16','yyyy-mm-dd')
    (即在查询之外执行算术)
  • SubmittedDateTo
    设为字符串,并将“
    截止日期('SubmittedDateTo','yyyy-mm-dd')
    +1”用作
    中的第二个条件,其中
  • 然后,查询速度显著加快(小于1秒,而大于44秒)

    进一步资料:

    • 对查询运行解释计划时会出现错误
      ORA-00932:不一致的数据类型:预期的日期获取编号
    • submitted\u date
      列有一个索引,并且统计数据等已经运行
    • trunc()
      调用中包装
      SubmittedDateTo+1
      ,不会影响性能
    • 我们没有具有类似数据量等的非9i数据库来测试它是否是Oracle版本

    问题是:我们找不到任何明确说明Oracle 9i优化器存在此类日期算法问题的信息。这就是这里发生的事情还是发生了其他事情?

    我始终确保显式处理所有转换(并假设o.submitted\u date是一个日期数据类型):

    这确保了在任何隐式转换中都没有错误,并且所有转换在其数据类型中都是明显的

    “问题是:我们找不到任何明确说明Oracle 9i Optimizer在这种日期算法方面存在问题的信息。这是在这里发生的还是在发生其他事情?”

    我不认为它是乐观主义者,它可能是导致性能问题的隐式转换的最终产物。由于我们没有从Oracle数据库中为日期等设置NLS,所以很难判断,但是如果使用显式转换可以提高性能,那么我建议您使用它们(而且这也是更好的做法)

    希望有帮助,Ollie。

    根据(这是v10,但我想这也适用于9i),“……不支持对执行日期绑定变量隐式类型转换的语句执行解释计划。”

    除了Ollie建议的方法外,您是否尝试过使用trunc()resp。而不是在两者之间

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


    您是否能够使用测试用例(例如,从dba_对象或类似对象构建的表)复制问题。尚未尝试。我限制了DB权限,因为我是应用程序开发人员,而不是dba方面的人员……您的Java代码是否将日期或字符串绑定到?我们将绑定到?使用
    java.sql.Timestamp
    对象。请参见Ollie的问题,了解真正的问题是什么。Frank,TRUNC()是否会导致乐观主义者忽略日期字段上的任何索引。FWIW,我会在?+我只是想说清楚我在做什么。你是对的,trunc()确实会这样做(除非你有一个基于trunc(submitted_date)的函数索引)。请参阅Ollie答案下的注释,了解真正发生的事情。为完整起见,使用trunc()不会影响性能。使用
    between
    是可行的,因为它在语义上是不等价的(
    between
    意味着
    Ollie,我接受这个答案,因为你的建议是正确的,这不是由于优化器。我对查询进行了更多的处理(在我没有显示的位中),我们有一个冗余的连接到一个表中,我们没有给它一个索引提示,它正在向下拖动。非常奇怪的是,要么修复索引,要么使用原始查询(带有连接/索引问题)使用预先计算的日期算法将加快查询速度。如果同时使用join/index+预先计算的算法,则查询速度会稍微快一点。不过,我仍然不明白为什么更改日期算法会涉及索引问题。。。
    
    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;
    
    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; 
    
    SELECT
        o.contact_id, 
        o.completed_date, 
        o.submitted_date
    FROM
        orders o /* 860,000 row table */
    WHERE   
        trunc(o.submitted_date) = trunc(?)
    
    SELECT
        o.contact_id, 
        o.completed_date, 
        o.submitted_date
    FROM
        orders o /* 860,000 row table */
    WHERE   
        o.submitted_date between ? and ? + 1