簡體   English   中英

在 WHERE 子句中調整 DECODE() 語句的性能

[英]Performance tuning a DECODE() statement in a WHERE clause

我重新編寫了一個查詢以減少選擇記錄所需的時間。 但是我仍然看到,由於成本很高,因此需要在解碼線中進行一些小調整。 有人可以告訴我是否可以在沒有解碼功能的情況下重寫相同的查詢嗎? 刪除解碼 function 的目的是使用v_id列中的索引。

到目前為止我所嘗試的。

  1. 嘗試創建 function 索引(知道無法使用綁定變量)但失敗了。
  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;

我建議將代碼編寫為:

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()很難理解。 一個簡單的 boolean or等效的。
  • 假設datet不在未來,則BETWEEN是不必要的。
  • 不需要SUM(NVL()) ,因為NULL值被忽略。 如果您擔心NULL結果,我建議COALESCE(SUM(dd.amt), 0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM