1

500k トランザクションのテーブルがあります。特定の日付の最後の残高を取得したい。そのため、以下のようなクエリを返しました。

    SELECT curr_balance
      FROM transaction_details
     WHERE acct_num = '10'
       AND is_deleted = 'N'
       AND ( value_date, srl_num ) IN(
            SELECT MAX( value_date ), MAX( srl_num )
              FROM transaction_details
             WHERE TO_DATE( value_date, 'dd/mm/yyyy' ) 
                <= TO_DATE( ADD_MONTHS( '05-APR-2012', 1 ), 'dd/mm/yyyy' )
              AND acct_num = '10'
              AND is_deleted = 'N'
              AND ver_status = 'Y' )
       AND ver_status = 'Y'        

これは、特定の月ごとの最後の残高を見つけるために、12 か月の増分に対して実行する必要があります。しかし、このクエリは CPU コストが高く、12 倍の時間がかかっています。上記のクエリを修正して、結果をより高速に取得する方法。これを PL/SQL で 2 つの部分に分割してパフォーマンスを実現できるかどうか。?

4

2 に答える 2

0

試す:

select * from(
    SELECT value_date, srl_num, curr_balance
      FROM transaction_details
     WHERE acct_num = '10'
       AND is_deleted = 'N'
       AND ver_status = 'Y'  
       row_number() over (partition by trunc(value_date - interval '5' day,'MM') 
                         order by srl_num desc
                         ) as rnk
       )
where rnk = 1;

テーブルの各月の最後の srl_num の残高を含むレポートを取得します。

利点は、あなたのアプローチは 12 か月のレポートでテーブルを 24 回スキャンし、私のアプローチはテーブルを 1 回スキャンすることです。

分析関数は、srl_num の後の月の行を並べ替えて、当月のレコードのランクを取得します (句による分割)。

于 2013-01-21T14:43:08.777 に答える
0

テーブルを 2 回クエリする必要はありません。分析関数を使ってみる

SELECT t.curr_balance
    -- , any other column you want as long it is in the subselect.
FROM (
    SELECT
        trans.curr_balance
        , trans.value_date
        -- any other column you want
        , trans.srl_num
        , MAX(trans.srl_num) OVER(PARTITION BY trans.value_date, trans.srl_num) max_srl_num
        , MAX(trans.value_date) OVER(PARTITION BY trans.value_date, trans.srl_num) max_date
    FROM transaction_details trans
    WHERE TO_DATE( value_date, 'dd/mm/yyyy' ) <= TO_DATE( ADD_MONTHS( '01-APR-2012', 1 ), 'dd/mm/yyyy' )
        AND acct_num = '10'
        AND is_deleted = 'N'
        AND ver_status = 'Y'
) t
WHERE t.max_date = t.value_date
    AND t.max_srl_num = t.srl_num 

いくつかの考え。

  • なぜあなたは持っていますTO_DATE( value_date...か?あなたのデータ型ではありませんDATEか?その列にインデックスがある場合、これはインデックスを壊している可能性があります。
  • (これは大まかな推測です)srl_num最新の日付の最高値でない場合、誤った結果が得られ、行が返されない可能性があることに注意してください。
于 2013-01-21T14:30:54.160 に答える