web-dev-qa-db-ja.com

特定の値のみのインデックスを作成する

非常に頻繁に呼び出されるクエリがあるので、パフォーマンスを改善したいのですが、インデックスのサイズと、更新の挿入への影響を懸念している同僚もいます。

SELECT field1, field2 
  FROM table1 
  WHERE field3 = '101'
  AND   field2 = @variable

テーブル table1には約500万行ありますが、約2,000だけがfield3 = 101

 CREATE TABLE table1 (
   field1 varchar
   field2 int
   field3 int);

Oracle 11gでこれらの2000行に対してのみ(field2、field1)を作成してインデックスを作成することは可能ですか?
どうすればできますか?

2
András

データベースSQL言語リファレンス-CREATE INDEX

「Oracleは、ビットマップインデックスの場合を除いて、すべてのキー列がnullであるテーブル行にインデックスを付けません。」

デモ

create table t as select level as field3 from dual connect by level <= 1000000;
alter table t add field3_ind as (case when field3 = 101 then field3 end);
create index t_ix_field3_ind on t (field3_ind); 

select * from t where field3_ind = 101;

Execution Plan


select    segment_name
         ,segment_type
         ,bytes

from      dba_segments 

where     owner        =  'DMARKOVITZ' 
      and segment_name in ('T','T_IX_FIELD3_IND')

order by  segment_name             
;

+-----------------+--------------+----------+
| SEGMENT_NAME    | SEGMENT_TYPE | BYTES    |
+-----------------+--------------+----------+
| T               | TABLE        | 13631488 |
+-----------------+--------------+----------+
| T_IX_FIELD3_IND | INDEX        | 65536    |
+-----------------+--------------+----------+

追伸.
仮想列を使用すると、クエリがよりユーザーフレンドリーになります。

インデックスが次のように定義されている場合-

create index t_ix_field3 on t (case when field3 = 101 then field3 end); 

インデックスを使用するには、クエリは次のようになります-

select * from t where case when field3 = 101 then field3 end = 101;