2011-10-05 4 views
7

アクティブなアクティブなエントリを持つテーブルがあり、アクティブの場合はアクティブ= 1、アクティブでない場合はアクティブ= 0です。Oracle:テーブルの行のサブセットへのインデックス付け

私はこのテーブルにさまざまなインデックスを持っていますが、アプリケーションはアクティブなデータに対してのみクエリを実行するため、アクティブなエントリにはインデックスが必要です。非アクティブなデータは再びアクティブになる可能性があるため保存する必要がありますが、通常はインデックスを使用しない一括更新でのみ行われます。

非アクティブなエントリ(アクティブなエントリよりもますます多くのものがあります)の索引付けにはかなりのスペースが必要です。

create index an_idx on tab (active, col1, col2, ... , coln) where active = 1

このような何かをするには、Oracle(10グラム)での方法はありますか?

前の試み:

私はそうのようなときactive = 0 nullに最初の列を設定する機能ベースのインデックスを使用してみました:

create index an_idx on tab (decode(active, 1, 1, null), col1, col2, ... , coln)

しかし、Oracleは、まだインデックスに非アクティブの列を思わこの場合。

答えて

7

表をACTIVEでパーティション化し、ローカル索引を作成し、非アクティブ・パーティションの索引をUNUSABLEにします。これにより、非アクティブデータのインデックス作成に費やされる時間がなくなります。

create table tab(active number, col1 number, col2 number, col3 number) 
    partition by list(active) 
    (partition tab_active values(1), partition tab_inactive values(0)); 

create index tab_index1 on tab(col1) local; 

alter index tab_index1 modify partition tab_inactive unusable; 

しかし、いくつかの潜在的な欠点は、このアプローチにあります。インデックスの

  • ないすべての種類が使用できなくなることができます。
  • データベースで使用できないオブジェクトを使用するのは正常ではありません。人々はおそらくそれについて不平を言うか、それがバグであると想定し、それを再構築します。
  • truncateなどの操作によって、インデックスが自動的に再び使用可能になります。オラクル12cに

あなたはpartial indexesを使ってこれを実現することができます

create table tab(active number, col1 number, col2 number, col3 number) 
    partition by list(active) 
    (partition tab_active values(1) indexing on, 
    partition tab_inactive values(0) indexing off); 

create index tab_index1 on tab(col1) local indexing partial; 
1

私はこれが可能ではないと思います。いくつかのオプション

  1. があります。そのクエリ時間が
  2. 非アクティブな要素によって ほど影響を受けないように、アクティブ/非アクティブな項目のための2つのテーブルを作成し、管理する(...アクティブ、COL1)にインデックスを作成します2つのテーブルの間で物事を動かすことによってアクティブな状態
  3. 索引付けするすべてのデータと一意の識別子を持つ2番目の表を作成し、残りのデータを取得するために表に結合します。
+0

スペースの節約があなたの目標である場合は、オプション2は、IMO理にかなって。 –

11

あなたの基本的な考えは正しいですが、すべての列にデコードを適用する必要があります。すべての索引付けされた式がNULLの場合のみ、その行は索引付けされません。もちろん

create index an_idx on tab (
    decode(active, 1, col1, null), 
    ... 
    decode(active, 1, coln, null) 
) 

あなたはその後、クエリはこのインデックスを使用したい場合は、それはWHERE句で同じ表現を使用する必要があります。

注インデックス番号decode(active, 1, 1, null)をインデックスに含めるとは限りません。インデックス付きのすべての行では定数であるためです。

+0

解決に感謝します。私はこのように何か面倒なことをしなければならないと心配していた。何かクリーナーがあるかもしれないと思った。 – Clinton

関連する問題