0

A のレコードが B の複数のレコードにマップされている 2 つのテーブル A と B があります。テーブル A のレコードと、テーブル B のマップされたすべてのレコードを次のように 1 行で表示するクエリがあります。

TABLE A
--------
ID  Name  Tag ......
1    X    213
2    Y    222

TABLE B
--------
ID    ACCESS_AREA
1     101
1     104
1     105
2     101
2     103

クエリは次のようになります。

SELECT ID,
       Name,
       Tag ,.....,
       (SELECT WM_CONCAT(ACCESS_AREA)
          FROM B
          WHERE ID = A.ID ) Access_areas
  FROM A

上記は機能しますが、両方のテーブルのレコード数が非常に多いため、クエリのパフォーマンスは非常に低くなります。フィルター処理や並べ替えを行うと、access_areasパフォーマンスがさらに低下します。

マテリアライズド ビューを使用して事前に値を計算することを考えたので、単純な結合になりますが、mv では、集計関数を使用したそのようなクエリのコミット時に高速更新を行うことはできません。

もう 1 つのオプションは、B から計算された値を含むテーブル A に列を追加し、変更が行われた場合にテーブル B でトリガーを使用して新しい列を更新することでした。ただし、トリガーがある同じテーブルをクエリできないため、これも実行できません。

最後の手段として、2 番目のオプションを実装し、アプリケーション コードを使用して列を更新することにしましたが、これは非常に面倒です。

何か案は?

4

2 に答える 2

1

クエリの EXPLAIN プランも、テーブルに存在するインデックスも示していません。しかし、もっと重要なことは、このデータで何をしているのかを教えてくれなかったということです。一度に大量のデータにアクセスする必要があるのはなぜですか? なぜ結果を非正規化する必要があるのですか?

マテリアライズド ビューと、スナップショットの取得後に更新された生データの両方を組み込んだビューを作成できます (そして、有効ではなくなった更新されたエントリを削除する可能性があります)。追加しただけでは、具体的にアドバイスすることはできません。

于 2012-06-06T10:14:19.140 に答える
0

WM_CONCAT1. またはのいずれかにLISTAGG置き換えますCOLLECT

SQL と PL/SQL の間で頻繁にコンテキストが切り替わるため、大規模な文字列の集計は非常にコストがかかる可能性があります。 WM_CONCAT、およびSTRAGGは非常に人気がありますが、どちらも非常に非効率的です。11gR2 を使用している場合は、常にLISTAGG. まだ 11gR2 を使用していない場合は、COLLECTメソッドを使用してください。 このページでは、さまざまな方法について説明し、いくつかのパフォーマンス比較を行います。

2. マテリアライズド ビュー。

私はあなたがすでにそれを試したとあなたが言ったことを知っています.Materialized Viewの経験はあまりありませんが、この場合はうまくいくはずです. 行 ID マテリアライズド ビューは機能しませんが、主キー マテリアライズド ビューは機能するはずです。

(それを妨げる他の特定の理由がない限り、その場合、問題をトラブルシューティングするためにすべての詳細が必要になる場合があります: テーブル、マテリアライズド ビュー、およびマテリアライズド ビュー ログの完全なクエリと DDL)。

3. 計画を説明します。

symcbean が述べたように、それは計画の問題である可能性があります。少数の行しか使用していない場合、インデックスは使用されていますか? ただし、説明計画に加えて、このクエリに対する期待を知る必要があります。クエリに 1 秒かかるが、200KB のデータが返される場合は、ネットワークまたはブラウザーが本当のボトルネックである可能性があります。


#2 または #3 が役立つかどうかはわかりませんが、常に #1 を実装する必要があります。私はWM_CONCATSTRAGGをバグだと考えています - はるかに優れた代替手段がある場合にそれらを使用する正当な理由はありません。

于 2012-06-07T09:57:50.487 に答える