次のようなOracleTextインデックスを作成しました。
create index my_idx on my_table (text) indextype is ctxsys.context;
そして、私は次のことを行うことができます:
select * from my_table where contains(text, '%blah%') > 0;
しかし、このテーブルに別の列があるとしましょう。たとえばgroup_id
、、代わりに次のクエリを実行したいとします。
select * from my_table where contains(text, '%blah%') > 0 and group_id = 43;
上記のインデックスを使用すると、Oracleは、を含むすべてのアイテムを検索してから'blah'
、それらのすべてをチェックする必要がありgroup_id
ます。
理想的には、でアイテムのみを検索しgroup_id = 43
たいので、次のようなインデックスが必要です。
create index my_idx on my_table (group_id, text) indextype is ctxsys.context;
通常のインデックスのようなものなので、それぞれに対して個別のテキスト検索を実行できますgroup_id
。
Oracleでこのようなことをする方法はありますか(それが重要な場合は10gを使用しています)?
編集(説明)
100万行、次の2列、A
およびB
、両方が数値であるテーブルについて考えてみます。500個の異なる値A
と2000個の異なる値がありB
、各行が一意であるとします。
では、考えてみましょうselect ... where A = x and B = y
でインデックスを作成しA
、B
私が知る限り、でインデックス検索を実行するB
と、500の異なる行が返され、これらの行で結合/スキャンが実行されます。いずれの場合も、少なくとも500行を調べる必要があります(データベースが幸運で、必要な行を早期に見つけることは別として)。
上のインデックス(A,B)
ははるかに効果的ですが、1つのインデックス検索で1つの行を検索します。
別々のインデックスを付けてgroup_id
、私が感じるテキストは、クエリジェネレータに2つのオプションしか残していません。
(1)group_id
インデックスを使用し、結果のすべての行をスキャンしてテキストを探します。
(2)テキストインデックスを使用し、結果のすべての行をスキャンして。を探しますgroup_id
。
(3)両方のインデックスを使用し、結合します。
私が欲しいのに対して:
(4)インデックスを使用して(group_id, "text")
、特定のテキストインデックスを検索し、group_id
そのテキストインデックスをスキャンして、必要な特定の行を探します。でインデックスを使用する場合のように、スキャンやチェック、結合は必要ありません(A,B)
。