2010-02-04 39 views
2

我在Oracle(10g XE)數據庫中有一個表,我將清理它並僅保留每個帳戶的三個最近記錄。下面是我在做什麼現在:提高保持每個帳戶查詢的三個最近記錄的性能

CREATE TABLE ACCOUNT_TRANSACTION_TMP NOLOGGING AS SELECT * FROM ACCOUNT_TRANSACTION WHERE 1=2; 


DECLARE 
    CURSOR mbsacc_cur (account_id_var account_transaction.account_id%TYPE) IS 
     SELECT * FROM account_transaction WHERE account_id = account_id_var ORDER BY transaction_time DESC; 

    account_transaction_rec account_transaction%ROWTYPE; 
BEGIN 
    FOR i IN (SELECT DISTINCT(account_id) FROM account_transaction) LOOP 
     OPEN mbsacc_cur(i.account_id); 
     LOOP 
      FETCH mbsacc_cur INTO account_transaction_rec; 
      EXIT WHEN mbsacc_cur%NOTFOUND OR mbsacc_cur%ROWCOUNT > 3; 
      INSERT /*+ append */ INTO account_transaction_tmp VALUES account_transaction_rec; 
     END LOOP; 
     CLOSE mbsacc_cur; 
    END LOOP; 
END; 
/

然後我就刪除舊錶,重新命名這個新老一個和添加約束。

但問題是上面的代碼運行了大約一百萬條記錄(約3-4小時),其中大約一半的記錄應該被刪除。

有什麼辦法可以提高這個性能嗎?

回答

3

而不是創建一個空表,並在RBAR方式填充創造你想要的行的表的....

CREATE TABLE ACCOUNT_TRANSACTION_TMP NOLOGGING AS 
SELECT account_id, col1, col2, col3, transaction_time from 
    (select at.* 
      , row_number() 
        over (partition by at.account_id 
         order by at.transaction_time desc) as to_keep 
FROM ACCOUNT_TRANSACTION at) 
where to_keep <= 3 
/

然後直接跳到您計劃的重命名部分。