0

ランク()操作を使用して最新のDHCPログイベントをIPアドレスに照合し、IPをホスト名に関連付けるウィンドウ関数があります。問題は、クエリが大規模なデータセットにうまくスケーリングしないことです。そのため、group byの観点からクエリを書き直したいのですが、成功していません。

create table large_table as
select column1, column2, column3, column4, column5, column6
from
(
  select 
    a.column1, a.column2, a.start_time,
    rank() OVER( 
      PARTITION BY a.column2, a.column1 order by a.start_time DESC 
    ) as rank,
    last_value( a.column3) OVER (
      PARTITION BY a.column2, a.column1 order by a.start_time ASC
      RANGE BETWEEN unbounded preceding and unbounded following 
    ) as column3,
    a.column4, a.column5, a.column6
  from 
    (table2 s 
      INNER JOIN table3 t 
      ON s.column2=t.column2 and s.event_time > t.start_time 
    ) a
 ) b
 where rank =1;

質問1:ウィンドウ関数の代わりにgroup byを使用して、上記のクエリをどのように書き直すのですか?

4

1 に答える 1

1

この種の方法で group-by として記述されたウィンドウを実行することが勝利戦略になるとは思いません。これにより、テーブルの集計をメイン テーブルに結合するときに、パフォーマンスが大幅に低下する可能性があります。

より良いアプローチは、plpgsql とループ内にウィンドウ情報を追加する関数を使用することです。たとえば、rownumber は次のように追加できます。

CREATE OR REPLACE FUNCTION foo_with_rownumber () RETURNS SETOF foo_with_rownumber
LANGUAGE PLPGSQL AS $$
DECLARE out_val foo_with_rownumber;
        iter int;
BEGIN
    iter := 1;
    FOR out_val IN select f.*, 0 FROM foo order by bar
    LOOP
        out_val.rownumber = iter;
        return next out_val;
        iter := iter + 1;
    END LOOP;
END;
$$;

rank() を追加すると少し複雑になるだけなので、これでうまくいくはずです。

于 2013-04-07T13:35:27.393 に答える