2022.01.12
エキス Context Indexの理解と活用方法

概要
普遍的に、Oracleを含むさまざまなリレーショナルデータベースは、B * Tree Indexを使用したインデックス付け技術を導入して使用しました。
B * Tree Indexは、いくつかのデータ型(numbers、string、etc)にさまざまなアプローチを提供することによって DBMSで最も頻繁に使用されるIndexになりました。
B * Tree Indexの拡張性の欠如の欠点を満たすために、Function based Index、Reverse Index、およびBitmap IndexなどのさまざまなIndexを作成しましたが、ユーザーのニーズを完全に満たすことはできませんでした。
そのため、ユーザーのニーズを満たすために、Oracleは8iバージョンからユーザーが直接インデックスのタイプを作成して適用できるDomain Indexを解決策として提示しました。
Oracleが提供するDomain Indexの中でも、Oracle Text Indexは、SQLワイルドカードマッチング機能を補完する機能を提供し、構造型/非構造型文書を検索する目的で活用される。
さらに、Oracle Text Indexは、大量のテキストでキーワード検索を実行する際のパフォーマンスの面でかなりの利点を期待できます。
これらの文書は、これらのOracle Text Indexの中でよく使用されるContext Indexを正確に理解し、効果的に使用する目的で作成されました。
Oracle Text Indexコンポーネント
Oracle Text Indexは、論理的にcontext type、ctxcat type、ctxrule typeで構成され、その中でContext Index物理的に$ I、$ K、$ R、$ N tableで構成されています。
各コンポーネントについて以下で詳しく確認してみましょう。
Oracle Text Index Types
Oracle Text Indexは、それぞれの性格とOperatorに応じて4つのタイプに分類できます。
Oracle Text Indexの4つの論理コンポーネントについて簡単にまとめると、次のようになります。
- Context type : サイズの大きい文書の full – text 検索に有利
- Ctxcat type : full-text 検索で価格、数量、場所などの構造的な検索に有利
- Ctxrule type: 文書を分析して分類するためのガラス
各Oracle Text Indexは、特性と使用形態、使用方法が異なるため、正確に動作方法を理解し、状況に適切に使用する必要があります。
この記事では、 最も一般的に使用されるContext Type Indexについて重点的に取り上げました。
Context Index Objects
Oracle Text Indexのうち、Context Indexは、格納する構造に応じて物理的に4つのコンポーネントに分けられます。Context Text Indexの物理コンポーネント4つについて簡単にまとめてみると以下の通りです。
- $Iテーブル:分割可能な文字列を「トークン」と呼ばれるテキストの小さな単位に分割して保存
- $Kテーブル:テーブルの各行にランダムに付与されたDOCIDを介してROWIDを保存する
- $R テーブル : テーブルの各行の ROWID を介してランダムに付与された DOCID を格納
- $Nテーブル:DELETEされたDOCIDを保存
対応するテーブルとインデックスはContext Index生成時に自動的に生成され、状況によっては生成から除外されるSegmentもある。
たとえば、特定のテーブルにInsertだけが実行されると仮定すると、Context Index生成時にDelete操作がないので、$Rテーブルと$Nテーブルは必要ないために生成されず、 $Iテーブル、 $Rテーブル、そして各テーブルに対応するインデックスのみが生成されます。
各テーブルの性格について正確に理解していれば、テーブルの性格に応じて重点的に監視すべきテーブルについて明確に判断することができます。
Context Indexの動作原理
TEXT |
EXEM |
MFO MFM |
DASHBOARD |
BIG DATA |
(オリジナルテーブル)
Context Indexは、生成時に元のテーブルの各ROWに対してDOCIDを付与し、各文字列をトークン単位で分割して$ Iテーブルに格納する。
TEXT | TOKEN_INFO |
EXEM | 1-1 |
MFO | 2-1 |
MFM | 2-2 |
DASHBOARD | 3-1 |
BIG | 4-1 |
DATA | 4-2 |
($|テーブル)
「EXEM」に対応するトークンは1-1、「MFO」に対応するトークンは2-1、「MFM」に対応するトークンは2-2、「DASHBOARD」に対応するトークンは3-1、「BIG ”に対応するトークンは4-1、“DATA”に対応するトークンは4-2のように指定される。
さらに、$ Iテーブルに対してパフォーマンスを向上させるために、B * Tree IndexであるX $インデックスが作成されます。
ユーザーが「TEXT = BIG DATA」という条件で検索すると、「BIG」、「DATA」という2つのトークンに分解され、そのトークンは$ Xインデックスを介して$ IテーブルにACCESSされます。
$ IテーブルからTOEKN_INFOの情報に基づいてDOCIDを返し、対応するDOCIDを使用して$ RテーブルからROWIDに変換され、元のテーブルを参照します。
コンテキストインデックスの監視方法
Context Indexは、各文字列に対してトークンという単位に分けて保存し、各トークンに対するウィッチ値、DOCIDとROWID変換に必要なデータなど多くの情報を格納する。
したがって、 Context Indexを作成した後は常にサイズを確認する必要があります。
Context Indexは内部的に複数のテーブルとインデックスで構成されるため、各Segmentsに対して確認する必要があります。
以下のテストでContext Indexのサイズを監視する方法を見てみましょう。
Context Index テストテーブルの作成 |
<< Context Indexサイズの確認>> – TEST TABLEの生成とSQL_TEXT COLUMNのCONTEXT INDEXの生成 SELECT A.OWNER , B.INDEX_NAME、 B.INDEX_TYPE 、 A.SEGMENT_NAME、 A.SEGMENT_TYPE、 A.BYTES/1024 AS「SIZE(KB)」 FROM DBA_SEGMENTS A 、 DBA_INDEXES B WHERE INSTR( A.SEGMENT_NAME , UPPER( B.INDEX_NAME ) , 1 ) > 0 AND B.INDEX_TYPE = ‘DOMAIN’ AND B.OWNER = :B1 AND B.TABLE_NAME = :B2 ORDER BY 6 DESC; – BIND VARIABLE B1 = ‘MFO8MON’ B2 = ‘DOMAIN_TEST’ ![]() |
Context Indexの動作方法のテスト
今からContext Indexの生成および確認を含む動作要件、テーブルのデータにDMLが発生した場合、10046 Traceを介した内部動作についてテストを通じて確認してみよう。
まず、TESTテーブルを作成してContext Indexを作成します。
Context Indexの作成と確認 |
<< コンテキストインデックスの作成と確認>> – TEST TABLEの生成とSQL_TEXT COLUMNのCONTEXT INDEXの生成 CREATE TABLE DOMAIN_TEST AS SELECT SQL_TEXT FROM V $ SQL; CREATE INDEX DOMAIN_TEST_IDX ON DOMAIN_TEST( SQL_TEXT ) INDEXTYPE IS CTXSYS.CONTEXT; – TEST TABLEで正常にCONTEXT INDEX生成を確認する SELECT INDEX_NAME、 TABLE_NAME、 STATUS、 ITYP_OWNER、 ITYP_NAME、 DOMIDX_STATUS 、 DOMIDX_OPSTATUS FROM DBA_INDEXES WHERE INDEX_NAME = ‘DOMAIN_TEST_IDX’; ![]() |
Context Indexの条件節に従った使用テスト
生成されたContext Indexに対して、さまざまな条件に応じて使用するかどうかについて、以下のテストで確認してみましょう。
Context Indexの作成と確認 |
<<Query Operatorを使用するかどうかに応じてContext Indexを使用するテスト>> – LIKE条件句のみを使用する場合は、照会SQLと実行計画 SELECT SQL_TEXT FROM DOMAIN_TEST A WHERE SQL_TEXT LIKE ‘UPDATE%’; ————————————————– ——————————————— | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ——————————————— | 0 | SELECT STATEMENT | | | | 241(100)| | |* 1 | TABLE ACCESS FULL | DOMAIN_TEST | 336 | 164K | 241 (0)| 00:00:01 | ————————————————– ——————————————— – LIKE条件付きおよびDOMAIN INDEXを使用するHINT使用する場合は、照会SQLと実行計画 SELECT /*+ INDEX(A DOMAIN_TEST_IDX) */ SQL_TEXT FROM DOMAIN_TEST A WHERE SQL_TEXT LIKE ‘UPDATE%’; ————————————————– ——————————————– | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ——————————————– | 0 | SELECT STATEMENT | | | | 241(100)| | |* 1 | TABLE ACCESS FULL | DOMAIN_TEST | 336 | 164K | 241 (0)| 00:00:01 | ————————————————– ——————————————– – Query Operator(contains)使用時の照会SQLと実行計画 SELECT SQL_TEXT FROM DOMAIN_TEST A WHERE CONTAINS(SQL_TEXT,’UPDATE’)>0; ————————————————– ————————————————– ———— | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ————————————————– ———— | 0 | SELECT STATEMENT | | | | 6(100)| | | 1 | TABLE ACCESS BY INDEX ROWID | DOMAIN_TEST | 9 | 4626 | 6 (0)| 00:00:01 | |* 2 | DOMAIN INDEX | DOMAIN_TEST_IDX | | | 4 (0)| 00:00:01 | ————————————————– ————————————————– ————- |
Text検索に一般的に使用されるLike条件については、Context Indexがあるにもかかわらず、Full Table Scanを通じて結果を出力します。
Like条件とともに「INDEX(<table_alias> <index_name>)」Hintを介してContext Indexを使用するように明示した結果でも同様にFull Table Scanを通じて結果を出力することが確認できる。
上記の結果のうち、条件句にContains構文を使用したQueryでのみ、Context Indexを使用することを確認できます。もしそうなら、Contains構文の使い方について以下のテストを通して明確に調べよう。
Contains 構文の使用法のテスト |
<<Query Operatorを使用するかどうかに応じてContext Indexを使用するテスト>> – LIKE条件句のみを使用する場合は、照会SQLと実行計画 SELECT SQL_TEXT FROM DOMAIN_TEST A WHERE SQL_TEXT LIKE ‘UPDATE%’; ————————————————– ——————————————— | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ——————————————— | 0 | SELECT STATEMENT | | | | 241(100)| | |* 1 | TABLE ACCESS FULL | DOMAIN_TEST | 336 | 164K | 241 (0)| 00:00:01 | ————————————————– ——————————————— – LIKE条件付きおよびDOMAIN INDEXを使用するHINT使用する場合は、照会SQLと実行計画 SELECT /*+ INDEX(A DOMAIN_TEST_IDX) */ SQL_TEXT FROM DOMAIN_TEST A WHERE SQL_TEXT LIKE ‘UPDATE%’; ————————————————– ——————————————– | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ——————————————– | 0 | SELECT STATEMENT | | | | 241(100)| | |* 1 | TABLE ACCESS FULL | DOMAIN_TEST | 336 | 164K | 241 (0)| 00:00:01 | ————————————————– ——————————————– – Query Operator(contains)使用時の照会SQLと実行計画 SELECT SQL_TEXT FROM DOMAIN_TEST A WHERE CONTAINS(SQL_TEXT,’UPDATE’)>0; ————————————————– ————————————————– ———— | Id | Operation | 名前 | Rows | Bytes | Cost(%CPU)| Time | ————————————————– ————————————————– ———— | 0 | SELECT STATEMENT | | | | 6(100)| | | 1 | TABLE ACCESS BY INDEX ROWID| DOMAIN_TEST | 9 | 4626 | 6 (0)| 00:00:01 | |* 2 | DOMAIN INDEX | DOMAIN_TEST_IDX | | | 4 (0)| 00:00:01 | ————————————————– ————————————————– ————- |
結論
これまで、Context Indexのコンポーネントや動作原理、内部動作方式について確認してみた。
テストで確認したように、Context Type Indexは名前から通常のIndexのように誤解することがありますが、実際にはさまざまなテーブルとインデックスで構成される1つのセットと見なすことができます。
文字列をすばやく検索できるという利点がありますが、元のテーブルの文字列の値をトークン単位で分割して保存し、そのトークンに関する位置情報やその他の付随的な情報を保存しているので、テーブルスペースの空き領域に十分確認が必要です。
また、Context IndexはSELECT、DML、DDLの場合、通常のIndexとは異なる動作をするため、正確に動作方式や原理について理解して使用しなければならない。
Oracleでは、8iから21cまでのバージョンが上がるにつれて、Oracle Textの新機能とオプションが追加されています。そのため、今後は活用度がさらに高まると予想されます。
このように進化し続けているContext Indexについて正確に理解し、必要な状況で適切に使用されれば、文字列検索時にパフォーマンス改善部分で満足のいく結果を得ることができます。