2014-10-30 106 views
0

我有一個過程內部下面的delete語句:甲骨文 - delete語句慢小桌子

delete t_excuse 
    where EMP_NO = AL_EMPNO 
    AND TO_CHAR(EXCUSE_DATE,'yyyymmdd') BETWEEN LS_STARTDATE_G AND LS_ENDDATE_G; 

這是慢約10秒。

但是當我添加任何選擇與相同的where子句然後執行刪除,它很快。

select count(*) 
into v_avariable from t_excuse 
     where EMP_NO = AL_EMPNO 
     AND TO_CHAR(EXCUSE_DATE,'yyyymmdd') BETWEEN LS_STARTDATE_G AND LS_ENDDATE_G; 

delete t_excuse 
     where EMP_NO = AL_EMPNO 
     AND TO_CHAR(EXCUSE_DATE,'yyyymmdd') BETWEEN LS_STARTDATE_G AND LS_ENDDATE_G; 
+1

t_excuse上是否定義了任何觸發器?任何索引?索引將在刪除時更新,並執行任何刪除觸發器 - 兩者都不會發生在select語句中,因此這可能是對性能差異的解釋。 – 2014-10-30 08:06:12

+0

沒有觸發器,但pk列上的默認索引 – 2014-10-30 08:07:55

+0

檢查整個數據模型中所有外鍵的索引。如果有缺失,請創建它們。 – nop77svk 2014-10-30 11:07:54

回答

0

TO_CHAR(EXCUSE_DATE, 'YYYYMMDD')之間LS_STARTDATE_G和 LS_ENDDATE_G

爲什麼你比較literaldate?避免implicit conversion。如果列的數據類型爲DATE,那麼只需使用日期列,TO_CHAR用於以您希望的格式顯示,TO_DATE用於操作。

delete t_excuse 
    where EMP_NO = AL_EMPNO 
    AND EXCUSE_DATE BETWEEN to_date(LS_STARTDATE_G,'yyyymmdd') 
         AND to_date(LS_ENDDATE_G,'yyyymmdd'); 

如果您在EXCUSE_DATE列有一個索引,那麼現在是Oracle將使用index。用新的查詢檢查解釋計劃。

編輯如果你真的想擺脫時間部分,使用TRUNC。但是,這會抑制INDEX的使用。您需要創建一個function-based索引作爲TRUNC(EXCUSE_DATE)

+0

由於時間部分也在日期我正在將列轉換爲to_char以消除時間部分 – 2014-10-30 08:10:39

+0

然後使用TRUNC並創建一個基於函數的索引作爲TRUNC(EXCUSE_DATE)。 – 2014-10-30 08:11:54

+0

早些時候嘗試過基於函數的索引作爲to_char(excuse_date,'yyyymmdd')它會服務於相同的 – 2014-10-30 08:26:38