问题
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.
- Tried creating a function index (Knowing that bind variables cannot be used) and it failed.
- 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, readableJOIN
syntax. (This does not affect performance, however.) decode()
is rather hard to follow. A simple booleanor
is equivalent.BETWEEN
is unnecessary assuming thatdatet
is not in the future.SUM(NVL())
is not needed, becauseNULL
values are ignored. If you are concerned aboutNULL
result, I would suggestCOALESCE(SUM(dd.amt), 0)
来源:https://stackoverflow.com/questions/65580294/performance-tuning-a-decode-statement-in-a-where-clause