【问题标题】:Performance tuning a DECODE() statement in a WHERE clause在 WHERE 子句中调整 DECODE() 语句的性能
【发布时间】:2021-04-11 06:51:47
【问题描述】:

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

到目前为止我已经尝试过什么。

  1. 尝试创建函数索引(知道无法使用绑定变量),但失败了。
  2. 已尝试使用 OR 条件,但它不会选择索引。所以任何建议都会有很大帮助。

查询如下:

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;

【问题讨论】:

  • 优化器似乎不太可能选择使用基于函数的索引。我希望该查询能够驱动表 DD,因为您对 ND_ID 和 A_ID 具有相等访问权限,然后它可能会选择使用索引来加入 ID 上的 DB。但其他标准看起来好像总是过滤器。
  • 不管怎样,这里没有足够的信息让任何人只能猜测,这浪费了我们所有的时间(包括你的)。我建议您阅读this excellent post on asking Oracle tuning questions,并可能编辑您的问题以提供更多详细信息。不过,我也建议你考虑一下是否真的有“需要做的小调整”。您希望减少查询的已用时间多少时间?它真的需要进一步调整吗?还是您的用户可以使用当前的ela t
  • 我会尽快分享解释计划。
  • 你的标题中的 Reg: 是什么意思?
  • 关于。对不起(没有特殊含义)

标签: sql oracle performance query-optimization


【解决方案1】:

我建议将代码编写为:

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_id, a_id, id, datet, code)
  • dd(dsba_id, datet, v_id)

对上述查询的更改:

  • 从不FROM 子句中使用逗号。始终使用正确、明确、标准、可读的JOIN 语法。 (不过,这不会影响性能。)
  • decode() 很难理解。一个简单的布尔值or 是等效的。
  • 假设datet 不在未来,BETWEEN 是不必要的。
  • 不需要SUM(NVL()),因为NULL 值被忽略。如果您担心NULL 的结果,我会建议COALESCE(SUM(dd.amt), 0)

【讨论】:

  • 也许decode 的重写在这种情况下是等价的(例如,如果v_id 列被声明为not null),但一般情况下并非如此。如果v_idxxxxxxxx 都是null,则decode 条件将返回true 而不管code;你的or重写不是这样。这种复杂性正是为什么有些人在这种情况下更喜欢decode;正确的重写(在所有种情况下等效)比您显示的要复杂。
  • 但是当我将其重写为 OR 条件时,我会得到更高的成本。我尝试过这种方式(在问题中提到)。问题是当我也使用 OR 条件时索引没有被选中
  • 正如我之前所说,您需要发布解释计划。做鬼脸和猜测是调整查询效率最低的方法:Oracle 提供了大量有关查询性能的具体信息,正是为了避免这类对话。
  • @VimalBhaskar 。 . . decode()or 确实应该对索引的使用没有影响。您是否尝试过此答案中指定的索引?
猜你喜欢
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
相关资源
最近更新 更多