Sql WHERE子句中DECODE()语句的性能优化

Sql WHERE子句中DECODE()语句的性能优化,sql,oracle,performance,query-optimization,Sql,Oracle,Performance,Query Optimization,我重新编写了一个查询,以减少选择记录所需的时间。但我仍然看到,由于成本很高,需要在解码线路上进行一些小的调整。有人能告诉我是否可以在没有解码功能的情况下重新编写相同的查询吗?删除解码功能的目的是使用v_id列中的索引 到目前为止我都试过了 尝试创建函数索引(知道无法使用绑定变量),但失败 已尝试使用或条件,但它不会选择索引。所以任何建议都会有很大帮助 查询如下: SELECT SUM(NVL(dd.amt,0)) FROM db,dd WHERE db.id = dd.dsba_id A

我重新编写了一个查询,以减少选择记录所需的时间。但我仍然看到,由于成本很高,需要在解码线路上进行一些小的调整。有人能告诉我是否可以在没有解码功能的情况下重新编写相同的查询吗?删除解码功能的目的是使用
v_id
列中的索引

到目前为止我都试过了

  • 尝试创建函数索引(知道无法使用绑定变量),但失败
  • 已尝试使用或条件,但它不会选择索引。所以任何建议都会有很大帮助
  • 查询如下:

    SELECT SUM(NVL(dd.amt,0))
      FROM db,dd
    WHERE db.id = dd.dsba_id
      AND dd.nd_id = xxxxxxx
      AND dd.a_id = 'xxxxx-xx'
      AND DECODE (db.v_id , xxxxxxxxx, 'COMPLETE' , db.code ) = 'COMPLETE'
      AND db.datet BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE;
    

    我建议将代码编写为:

    SELECT SUM(dd.amt)
    FROM db JOIN
         dd
         ON db.id = dd.dsba_id
    WHERE dd.nd_id = xxxxxxx AND
          dd.a_id = 'xxxxx-xx' AND
          (db.v_id = xxxxxxxxx OR db.code = 'COMPLETE') AND
          db.datet >= trunc(sysdate, 'YEAR');
    
    对于此查询,我建议使用以下索引:

    • db(nd\u id,a\u id,id,datet,code)
    • dd(dsba\u id,datet,v\u id)
    对上述查询的更改:

    • 切勿在
      FROM
      子句中使用逗号。始终使用正确、明确、标准、可读的连接语法。(但是,这不会影响性能。)
    • decode()
      很难理解。一个简单的布尔值
      是等价的
    • 假定
      datet
      不在将来,则不需要在
      之间执行
    • 不需要
      SUM(NVL())
      ,因为
      NULL
      值被忽略。如果您关心
      NULL
      结果,我建议
      COALESCE(SUM(dd.amt),0)

    优化器似乎不太可能选择使用基于函数的索引。我希望查询能够从表DD中删除,因为您在ND ID和A ID上有平等的访问权限,那么它可能会选择使用索引来连接ID上的DB。但是其他条件看起来似乎总是过滤器。无论如何,这里没有足够的信息,除了猜测之外,任何人都可以做任何事情,这是浪费我们的时间(包括你的问题)。我建议你阅读,或者编辑你的问题以提供更多细节。但是,我也建议你考虑是否真的有“需要做的小调整”。您预计需要多少时间来缩短查询的运行时间?它真的需要进一步调整吗?或者您的用户可以接受当前的
    ela t
    ?我将很快分享解释计划。您的标题中的Reg:是什么意思?关于。抱歉(没有特殊意义)在这种情况下,
    decode
    的重写可能是等效的(例如,如果
    v_id
    列声明为
    notnull
    ),但通常不是。如果
    v_id
    xxxxxxxx
    都是
    null
    decode
    条件将返回
    true
    ,而不管
    code
    ;对于
    重写,情况并非如此。这正是一些人在这种情况下更喜欢
    decode
    的原因;正确的重写rite(在所有情况下都是等效的)比您所展示的更复杂。但是,当我将其作为或条件重新编写时,我会得到更高的成本。我尝试了这种方法(在问题中提到)。问题是,当我使用或条件Too时,索引没有被选中。正如我前面所说,您需要发布解释计划。扮鬼脸和猜测是调整查询最不有效的方法:Oracle提供了大量有关查询性能的具体信息,以避免此类对话。@VimalBhaskar…The
    decode()
    的比较应该不会对索引的使用产生影响。您是否尝试了此答案中指定的索引?