4

数百のカーディナリティの高い列と数百万のレコードを持つテーブルに対するアドホック クエリのパフォーマンスを向上させる方法は?

私の場合、1 つのインデックス付きDATESDATE、1 つのVARCHAR2NE、および 750 の数値列を持つテーブルがあり、そのほとんどが の範囲の値を持つカーディナリティの高い列です0 to 100。テーブルはほぼ20000新しいレコードで 1 時間ごとに更新されます。このテーブルに対するクエリは次のようになります。

SELECT * FROM TAB WHERE SDATE BETWEEN :SDATE AND :EDATE AND V1 > :V1 AND V3 < :V3

また

SELECT * FROM TAB WHERE SDATE BETWEEN :SDATE AND :EDATE AND NE = :NE AND V4 > :V4

これまでのところ、日付インデックス アクセス パスから生成されるレコード数を制限するために、大きな間隔の日付を入力しないようにユーザーに常にアドバイスしてきました。ただし、場合によっては、より大きな間隔を指定する必要があります。

V1, V2, ..., V750すべてカーディナリティの低い列であれば、ビットマップ インデックスを利用できたはずです。残念ながらそうではありません。

これについてのアドバイスは何ですか?この問題にどのように取り組むべきですか?

ありがとう。

4

2 に答える 2

1

私はあなたがデザインに行き詰まっていると思うので、私がおそらく見ているいくつかの考え -

1) パーティションを使用する - パーティション分割オプションがある場合

2)いくつかのトリガーを使用して、クエリの使用法により最適化されたクエリテーブルを非正規化(またはこの場合は正規化)します

3) スナップショットを作成する

4) 日のレコード (または適切なサブセット) を持つ現在のテーブルまたはテーブルのセットを見て、それらを大きなテーブルにロールオーバーして履歴を保存します。

それは、使用パターンとシステムが持つ他のすべての制約に依存します。詳細があれば、より良い解決策がおそらくそこにあるでしょう。

于 2012-09-25T01:56:06.677 に答える
1

大きな問題はインサートだと思います。sdate にインデックスがあり、挿入が遅くなり、選択が高速になります。しかし、あなたの問題に戻ります:

ユーザーが大きな間隔 (5% を超えるとしましょう) を指定する場合は、テーブルを sdate で日単位、週単位、または月単位でパーティション分割することをお勧めします。 Oracle パーティショニングのドキュメント

(テーブルを分割する場合は、インデックスも分割することを忘れないでください。ライブで実行する場合は、を使用しますexchange partition)。

また、回避策として、強力なマシンを使用している場合は、並列クエリを使用できます。 Oracle パラレル ドキュメント

于 2012-09-25T05:56:32.540 に答える