0

このフィドルで矮小化された次のシナリオがあります。

データベース内で一度に大量の結果セット (1 億以上) のレコードを処理し、数値として表される権限を結合する必要があります。ビットごとの OR は、使用される集計です。Steve私の質問は、フィドルでエントリが次のようなタプルを返す ことを保証する最も効率的な方法は何ですか?

name     permissions   
Steve    23 --(bit_or)  

主な問題は私が見た時間を追跡することであることは知っていますSteveが、これを処理するための効率的な方法を推測することはできません. materialized view計算後の結果セットを処理できる ように、データベースでこれを実行することをお勧めします。

質問

ビットごとの or を使用した集計は、私には魅力的ではありません。そのマスクが既に適用されている別の列を作成できませんか?

応答

それが具体化されたビューに格納されるものです。どこかで計算する必要があります。問題は、これが常にデータが供給されるデータ ウェアハウス アプリケーションであり、これらのアクセス許可は、使用されているキャッシュ戦略に基づいてかなり頻繁に更新する必要があることです。

4

2 に答える 2

3

最も効率的な解決策は、おそらく直接 SQL 集計を実行することです。パーミッションは有限であるため、個々のパーミッションには一定の数 (N) があります。各権限を N 列に分解し、( を使用してMAX) 集計し、次の後に権限を再構成できます。

p1 = sign(BitAnd(permissions, 2^0))
p2 = sign(BitAnd(permissions, 2^1))
...
P1 = MAX(p1)
P2 = MAX(P2)
...

Permissions = 2^0 * P1 + 2^1 * P2 + ... + 2^(N-1) * PN

しかし、それは面倒で、新しいアクセス許可を追加するときにクエリを書き直す必要があります。

SQL> select name,
  2           power(2, 0) * MAX(sign(BitAnd(permissions, power(2, 0))))
  3         + power(2, 1) * MAX(sign(BitAnd(permissions, power(2, 1))))
  4         + power(2, 2) * MAX(sign(BitAnd(permissions, power(2, 2))))
  5         + power(2, 3) * MAX(sign(BitAnd(permissions, power(2, 3))))
  6         + power(2, 4) * MAX(sign(BitAnd(permissions, power(2, 4))))
  7         + power(2, 5) * MAX(sign(BitAnd(permissions, power(2, 5))))
  8         + power(2, 6) * MAX(sign(BitAnd(permissions, power(2, 6))))
  9         + power(2, 7) * MAX(sign(BitAnd(permissions, power(2, 7))))
 10         + power(2, 8) * MAX(sign(BitAnd(permissions, power(2, 8))))
 11            permissions
 12    from cats
 13   group by name;

NAME            PERMISSIONS
--------------- -----------
Carl                     15
Steve                    23

代わりに、独自のユーザー定義集計を作成することをお勧めします ( Tom Kyte によるこの投稿に触発され、9ir2 でテスト済み):

SQL> create or replace type bin_agg_type as object
  2  (
  3     total NUMBER,
  4
  5     static function
  6          ODCIAggregateInitialize(sctx IN OUT bin_agg_type )
  7          return number,
  8
  9     member function
 10          ODCIAggregateIterate(self IN OUT bin_agg_type ,
 11                               value IN NUMBER)
 12          return number,
 13
 14     member function
 15          ODCIAggregateTerminate(self IN bin_agg_type ,
 16                                 returnValue OUT NUMBER,
 17                                 flags IN number)
 18          return number,
 19
 20     member function
 21          ODCIAggregateMerge(self IN OUT bin_agg_type,
 22                             ctx2 IN bin_agg_type)
 23          return number
 24  );
 25  /

Type created.

SQL> create or replace type body bin_agg_type
  2  is
  3
  4  static function ODCIAggregateInitialize(sctx IN OUT bin_agg_type )
  5  return number
  6  is
  7  begin
  8      sctx := bin_agg_type ( 0 );
  9      return ODCIConst.Success;
 10  end;
 11
 12  member function ODCIAggregateIterate(self IN OUT bin_agg_type ,
 13                                       value IN NUMBER)
 14  return number
 15  is
 16  begin
 17      self.total := self.total + value - BitAND(self.total, value);
 18      return ODCIConst.Success;
 19  end;
 20
 21  member function ODCIAggregateTerminate(self IN bin_agg_type ,
 22                                         returnValue OUT NUMBER,
 23                                         flags IN number)
 24  return number
 25  is
 26  begin
 27      returnValue := total;
 28      return ODCIConst.Success;
 29  end;
 30
 31  member function ODCIAggregateMerge(self IN OUT bin_agg_type ,
 32                                     ctx2 IN bin_agg_type )
 33  return number
 34  is
 35  begin
 36      self.total := self.total+ctx2.total - BitAND(self.total, ctx2.total);
 37      return ODCIConst.Success;
 38  end;
 39
 40
 41  end;
 42  /

Type body created.

SQL> CREATE or replace
  2  FUNCTION BitOr_Agg(input NUMBER)
  3  RETURN NUMBER
  4  PARALLEL_ENABLE AGGREGATE USING bin_agg_type ;
  5  /

Function created.

それを呼びましょう:

SQL> SELECT name, bitor_agg(permissions) from cats group by name;

NAME            BITOR_AGG(PERMISSIONS)
--------------- ----------------------
Carl                                15
Steve                               23

どれが最速か知りたいです。

于 2012-11-13T16:37:58.710 に答える
0

これは、OracleにビットごとのOR集計関数が実装されているブログへのリンクです。

于 2012-11-13T16:35:21.210 に答える