Performance tuning a DECODE() statement in a WHERE clause

*爱你&永不变心* 提交于 2021-02-11 13:38:04

问题


I re-wrote a query to reduce the time it takes to pick the records. But still I see that there is a small tuning that needs to be done in the decode line as the cost is high. Can someone please let me know if the same query can be re-written without the decode functionality? The purpose of removing the decode function would be to use the index in v_id column.

What I have tried so far.

  1. Tried creating a function index (Knowing that bind variables cannot be used) and it failed.
  2. Have tried using the OR condition but it would not pick the index. So any suggestion would be of a great help.

Query is given below.:

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;

回答1:


I would suggest writing the code as:

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');

For this query, I would recommend indexes on:

  • db(nd_id, a_id, id, datet, code)
  • dd(dsba_id, datet, v_id)

The changes to the above query:

  • Never use commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax. (This does not affect performance, however.)
  • decode() is rather hard to follow. A simple boolean or is equivalent.
  • BETWEEN is unnecessary assuming that datet is not in the future.
  • SUM(NVL()) is not needed, because NULL values are ignored. If you are concerned about NULL result, I would suggest COALESCE(SUM(dd.amt), 0)


来源:https://stackoverflow.com/questions/65580294/performance-tuning-a-decode-statement-in-a-where-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!