【问题标题】:Improving the performance of keeping the three recent records of each account query提高保留每个帐户查询的三个最近记录的性能
【发布时间】:2010-02-04 07:42:38
【问题描述】:

我在 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 小时)约 100 万条记录,其中大约一半应该被删除。

有什么办法可以提高这个性能吗?

【问题讨论】:

    标签: performance oracle plsql


    【解决方案1】:

    与其创建一个空表并以 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
    /
    

    然后直接跳到计划的重命名部分。

    【讨论】:

      【解决方案2】:

      您可以通过分析来做到这一点(尽管我自己并不精通)。看看这个问题,它似乎解决了类似于你的情况:

      http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1212501913138

      【讨论】:

        猜你喜欢
        • 2018-07-09
        • 2017-08-05
        • 2020-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-30
        • 1970-01-01
        相关资源
        最近更新 更多