1.8 結果表を使用した問合せ実行の高速化
結果表は、RDFグラフまたはRDFグラフ・コレクションに対して実行されるSPARQL問合せの一般的なパターンの結果を格納する補助表です。
ノート:
結果表は、以前のブック・バージョン(Oracle Databaseリリース23aiより前)でSubject-Property-Matrix (SPM)表としてコールされました。詳細は、「用語とサブプログラムの変更」を参照してください。一般的なパターン問合せには、スターパターン、チェーン・パターンおよび単一トリプル・パターン問合せが含まれます。
結果表によるパフォーマンスの向上は、次を使用することで実現されます。
- これらの表で事前マテリアライズド結合を使用すると問合せ処理時の結合が減少します
- 別々の表内の個々のプロパティについてトリプルのコンパクト表現を使用するとアクセスがより迅速になります
- これらの表から取得した、より正確なRDFデータ統計を使用すると、問合せ実行計画が改善されます
次のセクションでは、結果表について詳しく説明します。
- 結果表のタイプ
RDFグラフまたはRDFグラフ・コレクションには、3つのタイプの結果表を定義できます。 - 結果表の作成と管理
以降の項では、結果表を作成および管理する手順について説明します。 - 結果表のSPARQL問合せオプション
SPARQL問合せでは、結果表が存在する場合、結果表が自動的に使用されます。 - 結果表を使用する場合の特別な考慮事項
この項では、結果表の使用時に考慮する必要があるいくつかの制限事項を説明します。
親トピック: RDFグラフの概要
1.8.1 結果表のタイプ
RDFグラフまたはRDFグラフ・コレクションには、3つのタイプの結果表を定義できます。
様々な結果表を次に示します。
- スターパターン表: これらの表には、次のようなスターパターン問合せの結果が保持されます(各プロパティは単一値である必要があります)。
?x :fname ?fnm . ?x miname ?m . ?x :lname ?lnm .
- トリプルパターン表: これらの表には、次のような単一のトリプルパターン問合せの結果が保持されます。
?x :hasHobby ?y .
これはRDFトリプルと同じですが、特定のプロパティの場合です。
- チェーンパターン表: これらの表には、次のようなチェーンパターン問合せの結果が保持されます。
?child :hasParent ?parent . ?parent :hasBrother ?uncle .
チェーンは、すべてのリンクが存在する場合にのみ格納されます。
ノート:
スターパターン表、トリプルパターン表、チェーンパターン表は、以前のブック・バージョン(Oracle Databaseリリース23aiより前)でそれぞれ単一値プロパティ(SVP)表、複数値プロパティ(MVP)表、プロパティ・チェーン(PCN)表と呼ばれていました。詳細は、「用語とサブプログラムの変更」を参照してください。次のサンプル・データを含むRDFグラフについて考えてみます。
:john :fname "John" ; :lname "Brown" ; :height 72 ; :email "john@email-example.com", "johnnyB@email-example.com" .
:mary :fname "Mary" ; :lname "Smith" ; :height 68 ; :email "Mary.Smith@email-example.com" .
:bob :fname "Robert" ; :lname "Brown" ; :height 70 ; :fatherOf :john, :mary ; :email "bobBrown@email-example.com" .
:alice :fname "Alice" ; :lname "Brown" ; :height 68 ; :motherOf :john, :mary .
:henry :fatherOf :bob .
:kathy :motherOf :bob .
なお、わかりやすくなるように、rdftermごとに実際の数値識別子(RDF_VALUE$
表にある)のかわりにId(rdfterm)が使用されます。例1-107には、追加データを含む完成した例が含まれています。
- スターパターン表
スターパターン表の各行には、RDFグラフ内のリソースの1つ以上の単一値RDFプロパティの値が含まれます。 - トリプルパターン表
特定のプロパティに対して作成されたトリプルパターン表の各行には、プロパティの値が保持されます。 - チェーンパターン表
チェーンパターン表内の各行には、RDFグラフの固定長のパスが保持されます。
親トピック: 結果表を使用した問合せ実行の高速化
1.8.1.1 スターパターン表
スターパターン表内の各行には、RDFグラフ内の1つのリソースについて1つ以上の単一値RDFプロパティの値が保持されます。
すべて理想的に進んだ場合には、n
個のプロパティについて定義されているスターパターン表を問合せ処理中に使用して、RDF_LINK$
表のn
方向結合を単純な表参照に置き換えることができます。
プロパティp
がRDFグラフでの単一値となるのは、名前付きグラフであるかどうかを問わず、グラフ内の各リソースにあるp
の値が最大でも1つの場合です。サンプルRDFデータセット(「結果表のタイプ」を参照)では、プロパティ:first_name
、:last_name
および:height
は単一値ですが、プロパティ:email
は複数値です。
単一値プロパティのみを使用する{ ?s :first_name ?fname ; :last_name ?lname ; :height ?height }
などの問合せパターンの実行を高速化するには、SEM_APIS.BUILD_RESULT_TABサブプログラムのコールで文字列':first_name :last_name :height'
をkey_string
パラメータの値として使用することで、前述の3つの単一値プロパティを含めてRDFグラフにスターパターン表を作成します。
表1-19に、前述のサンプル・データに対応するスターパターン表の構造と内容を示します。また、次のことに注意してください:
- この表は、実際の列セットのサブセットのみを示しています。厳密に述べると、対応するRDF文の名前付きグラフ・コンポーネントの格納に使用される
G<Id(property)>
のような名前の列は示していません。 - この表では、列の値を、格納される実際の数値識別子ではなく、
Id(rdfterm)
として示しています。
表1-19 スターパターンの表構造の例
START_NODE_ID | … | P<Id(:first_name)> | … | P<Id(:last_name)> | … | P<Id(:height)> |
---|---|---|---|---|---|---|
Id(:john) |
...
|
Id(“John”) |
... |
Id(“Brown”) |
... |
Id(72) |
Id(:mary) |
...
|
Id(“Mary”) |
... |
Id(“Smith”) |
...
|
Id(68) |
Id(:bob) |
... |
Id(“Robert”) |
... |
Id(“Brown”) |
... |
Id(70) |
Id(:alice) |
... |
Id(“Alice”) |
...
|
Id(“Brown”) |
...
|
Id(68) |
このスターパターン表を使用できることで、スターパターン表内の行にアクセスするだけで前述の問合せパターンを処理でき、そうでなければ必要な、RDF_LINK$表の3方向自己結合を回避できます。
単一値である逆プロパティを含めることもできます。サンプルRDFデータ(「結果表のタイプ」を参照)では、プロパティ:fatherOf
は単一値ではありませんが、^:fatherOf
(:hasFather
プロパティと直観的に同等)として示されるその逆バージョンは、実際には単一値です。{ ?s :fname ?fname; :lname ?lname; :height ?height; ^:fatherOf ?father }
などの問合せパターンの実行を高速化するには、':fname :lname :height ^:fatherOf'
をkey_string
値として使用することで、前述のスターパターン表の拡張バージョンを作成します。
表1-20に、逆プロパティを含む、この拡張バージョンのスターパターン表の構造と内容を示します。列名の先頭文字としてP
ではなくR
を使用することで(R<Id(:fatherOf)>
)、これが逆プロパティであることを示します。前述のように、このスターパターン表を使用できることで、RDF_LINK$
表の(4方向)自己結合を回避できます。
表1-20 逆プロパティを含む拡張スターパターン表
START_NODE_ID | … | P<Id(:first_name)> | … | P<Id(:last_name)> | … | P<Id(:height)> | … | R<Id(:fatherOf)> |
---|---|---|---|---|---|---|---|---|
Id(:john) |
... |
Id(“John”) |
... |
Id(“Brown”) |
... |
Id(72) |
... |
:bob |
Id(:mary) |
... |
Id(“Mary”) |
... |
Id(“Smith”) |
... |
Id(68) |
... |
:bob |
Id(:bob) |
... |
Id(“Robert”) |
... |
Id(“Brown”) |
... |
Id(70) |
... |
:henry |
例1-98 スターパターン表の作成
次のコードでは、M1
という名前のRDFグラフに拡張スターパターン表が作成されます。
BEGIN
SEM_APIS.BUILD_RESULT_TAB(
query_pattern_type => SEM_APIS.SPM_TYPE_SVP
, result_tab_name => 'FLHF'
, rdf_graph_name => 'M1'
, key_string => ' :fname :lname :height ^:fatherOf '
, prefixes => ' PREFIX : <http://www.example.com#> '
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
スターパターン表の名前、構造およびデフォルト索引は、次のように記述できます:
- スターパターン表の名前は、次のテンプレートに基づいて作成されます:
<NETWORK_NAME>#RDF_XT$SVP_<MODEL_NAME>+__<SPM_NAME>
NUMBER
列であるSTART_NODE_ID
には、スターパターン表内のプロパティのリストにおける最初のプロパティについて、一致するトリプルの、主語ID、または逆プロパティの場合は目的語IDが格納されます。- スターパターン表でカバーされているプロパティごとに、字句値の数値識別子をトリプルに格納するために次の列が作成されます:
- 指定されたグラフIDを格納するための
NUMBER
列(G<Id(property)>
)。 - 目的語IDを格納するための
NUMBER
列P<Id(property)>
、または逆プロパティの場合は主語IDを格納するためのR<Id(property)>
。 - (オプション)内部使用のためのその他の列。
- 指定されたグラフIDを格納するための
START_NODE_ID
列はスターパターン表の主キーとして定義され、テンプレート<NETWORK_NAME>#RDF_XX$SVP_<MODEL_NAME>_UQ__<SPM_NAME>
を使用して名付けられた一意の索引が、SVP表の作成時にこの列に作成されます。
親トピック: 結果表のタイプ
1.8.1.2 トリプルパターン表
指定されたプロパティ用に作成されたトリプルパターン表内の各行には、そのプロパティの値が保持されます。
トリプルパターン表には、別個の表内の指定されたプロパティの値がコンパクトな形式で格納されます。これにより、アクセスが迅速になり、統計が改善されます。スターパターン表と異なり、トリプルパターン表に含まれる(単一)プロパティは必須ではありませんが、単一値である可能性があります。
名前付きグラフであるかどうかを問わず、2つ以上のトリプルがあり、それらは(s p o1)
および(s p o2)
で、o1
はo2
と等しくない場合、RDFグラフではプロパティp
は複数値です。つまり、s
には、プロパティp
に対して複数の異なる目的語値があります。
サンプルRDFデータセット(「結果表のタイプ」を参照)では、プロパティ:email
、:fatherOf
および:motherOf
が複数値です。
表1-21に、前述のサンプル・データでの:motherOf
プロパティについて、トリプル・パターン表の構造と内容を示します。ここで示す2つの列には、変数?mom
および?c
の字句値の数値識別子が、それぞれパターン{ ?mom :motherOf ?c }
で格納されます。トリプルパターン表には、一致するRDF文がクワッドの場合に名前付きグラフの数値識別子を格納するために、ここに示されていない別の列G<id<:motherOf>)
が含まれています。
表1-21 トリプルパターンの表構造の例
START_NODE_ID | ... | P<Id(:motherOf)> |
---|---|---|
Id(:alice) |
Id(:john) |
|
Id(:alice) |
Id(:mary) |
|
Id(:kathy) |
Id(:bob) |
例1-99 トリプルパターン表の作成
M1という名前のRDFグラフで前述のトリプル・パターン表を作成するには、次のSQLコマンドを使用します。
BEGIN
SEM_APIS.BUILD_RESULT_TAB(
query_pattern_type => SEM_APIS.SPM_TYPE_MVP
, result_tab_name => null /* must be NULL (the name is auto-generated based on id(property) */
, rdf_graph_name => 'M1'
, key_string => ' :motherOf ' /* must have exactly one property */
, prefixes => ' PREFIX : <http://www.example.com#> '
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
トリプルパターン表の名前、構造およびデフォルト索引は、次のように記述できます:
- トリプルパターン表の命名規則は、次のテンプレートに基づいて作成されます:
<NETWORK_NAME>#RDF_XT$MVP_<MODEL_NAME>+__P<id(property)>
NUMBER
列であるSTART_NODE_ID
には、ターゲット・プロパティを述語として使用する、一致するトリプルの主語IDが格納されます。- トリプル・パターン表でカバーされているプロパティについて、字句値の数値識別子をトリプルに格納するために次の列が作成されます:
- 指定されたグラフIDを格納するための
NUMBER
列G<Id(property)>
。 - 目的語IDを格納するための
NUMBER
列P<Id(property)>
- 内部使用のための、オプションのその他の列
- 指定されたグラフIDを格納するための
- 一意でない索引が、
<NETWORK_NAME>#RDF_XX$MVP_<MODEL_NAME>_P<id(property)>
という命名規則を使用してSTART_NODE_ID
列に作成されます。
親トピック: 結果表のタイプ
1.8.1.3 チェーンパターン表
チェーンパターン表内の各行には、RDFグラフでの固定長のパスが含まれます。
パスは一連の2つ以上のトリプルであり、シーケンス内の最後のトリプルを除き、トリプルの目的語は次のトリプルの主語と同じです。長さn
のパスが格納されているチェーンパターン表を問合せ処理中に使用して、RDF_LINK$
表のcurrent_triple.object = next_triple.subjectタイプのn
方向結合を単純な表参照に置き換えることができます。
たとえば、{ ?gma :motherOf ?f . ?f :fatherOf ?c }
という問合せパターンの実行を高速化するには、key_string
として指定された一連のプロパティ(' :motherOf :fatherOf '
)を使用してチェーンパターン表を作成します。
表1-22に、前述のサンプル・データでのチェーンパターン表の構造と内容を示します。ここで示す3つの列には、プロパティ・チェーンを満たす2つのパス((:kathy) –[:motherOf]-> (:bob) –[:fatherOf]-> (:john)
および(:alice) –[:motherOf]-> (:bob) –[:fatherOf]-> (:mary)
)について、変数?gma, ?f, and ?c
の字句値の数値識別子がそれぞれ格納されます。
表1-22 チェーンパターンの表構造の例
START_NODE_ID | … | P<Id(:motherOf)> | … | P<Id(:fatherOf)> |
---|---|---|---|---|
Id(:kathy) |
... |
Id(:bob) |
... |
Id(:john) |
Id(:kathy) |
... |
Id(:bob) |
...
|
Id(:mary) |
プロパティ・チェーンには、同じプロパティの複数出現を含めることができます。祖父を子に結び付ける次の問合せパターンを考えてみます:
{ ?gfa :fatherOf ?f . ?f :fatherOf ?c }
key_string
として指定された一連のプロパティ' :fatherOf :fatherOf '
を使用してチェーンパターン表を作成できます。次の表に、このようなチェーン・パターン表の構造と内容を示します。'#2
'という接尾辞が付いた列名は、指定されたチェーン内の:fatherOf
プロパティの2回目の出現に対応しています。それには、プロパティ・チェーンを満たす2つのパス((:henry) –[:fatherOf]-> (:bob) –[:fatherOf]-> (:john)
および(:henry) –[:fatherOf]-> (:bob) –[:fatherOf]-> (:mary)
)が格納されます。
表1-23 チェーンパターン表での単一プロパティの複数出現
START_NODE_ID | … | P<Id(:fatherOf)> | … | P<Id(:fatherOf)>#2 |
---|---|---|---|---|
Id(:henry) |
... |
Id(:bob) |
... |
Id(:john) |
Id(:henry) |
...
|
Id(:bob) |
...
|
Id(:mary) |
プロパティ・チェーンには、逆プロパティも含まれている場合があります。たとえば、兄弟に結び付ける問合せパターン{ ?mom :motherOf ?c . ?c ^:fatherOf ?dad }
を考えてみます。key_string
として':motherOf ^:fatherOf '
を使用してチェーンパターン表を作成できます。
表1-24に、このチェーンパターン表の構造とコンテンツを示します。なお、右端の列名R<id(:fatherOf)>
にある文字'R
'は、その列が逆プロパティに対応していることを示しています。このチェーンパターン表を使用できることで、チェーンパターン表内の行にアクセスするだけで前述の問合せパターンを処理でき、そうでなければ必要な、RDF_LINK$
の2方向結合を回避できます。
表1-24 チェーンパターン表の逆プロパティ
START_NODE_ID | … | P<Id(:motherOf)> | … | R<Id(:fatherOf)> |
---|---|---|---|---|
Id(:alice) |
...
|
Id(:john) |
... |
Id(:bob) |
Id(:alice) |
...
|
Id(:mary) |
...
|
Id(:bob) |
Id(:kathy) |
...
|
Id(:bob) |
...
|
Id(:henry) |
例1-100 チェーンパターン表の作成
次の例では、M1
という名前のRDFグラフで:fatherOf
プロパティの2回出現を使用して、祖父チェーンを表すチェーン・パターン表を作成します。
BEGIN
SEM_APIS.BUILD_RESULT_TAB(
result_tab_name => ‘GRANDPA’
, query_pattern_type => SEM_APIS.SPM_TYPE_PCN
, rdf_graph_name => 'M1'
, key_string => ' S :fatherOf :fatherOf '
, prefixes => ' PREFIX : <http://www.example.com#> '
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
チェーンパターン表の名前、構造およびデフォルト索引は、次のように記述できます:
- チェーン・パターン表の名前は、次のテンプレートに基づいています:
<NETWORK_NAME>#RDF_XT$PCN_<MODEL_NAME>+__<SPM_NAME>
NUMBER
列であるSTART_NODE_ID
には、チェーンパターン表内のプロパティのシーケンスにおける最初のプロパティについて、一致するトリプルの、主語ID、または逆プロパティの場合は目的語IDが格納されます。- チェーンパターン表でカバーされている各プロパティのn回目の出現ごとに、字句値の数値識別子をトリプルに格納するために次の列が作成されます(なお、
#n
接尾辞は、n > 1
の場合のみ使用されます):- 指定されたグラフIDを格納するための
NUMBER
列G<Id(property)>
(またはG<Id(property)>#n
) - 目的語IDを格納するための
NUMBER
列P<Id(property)>
(またはP<Id(property)>#n
)、または逆プロパティの場合は主語IDを格納するためのR<Id(property)>
(またはR<Id(property)>#n
) - (オプション)内部使用のためのその他の列
- 指定されたグラフIDを格納するための
- テンプレート
<NETWORK_NAME>#RDF_XX$PCN_<MODEL_NAME>__<SPM_NAME>
を使用して名付けられた一意でない索引が、START_NODE_ID
列に作成されます。 - また、各プロパティ列に、一意でない索引が作成されます。
親トピック: 結果表のタイプ
1.8.2 結果表の作成および管理
以降の項では、結果表を作成および管理する手順について説明します。
- 結果表への字句値のインクルード
結果表には、目的語の字句値も含めることができます。 - 結果表でのセカンダリ索引の作成と削除
結果表のセカンダリ索引を作成および削除できます。 - 結果表の削除
特定の結果表を削除できます。 - インメモリー結果表
Oracle Database In-Memoryを利用すると、オプション・パラメータでINMEMORY=T
フラグを使用してインメモリー結果表を作成できます。 - 結果表のメタデータ
RDF_SPM_INFOビューを使用して、RDFグラフで定義された結果表のメタデータ情報を取得できます。 - 個別プロパティについて主語ごとのカーディナリティ集計を計算するためのユーティリティ・サブプログラム
SEM_APIS.GATHER_SPM_INFOプロシージャを使用すると、トリプルの述語としての用途に基づいて、RDFグラフ内の各プロパティについて、主語ごとのカーディナリティ情報を格納する表を作成しデータを移入できます。 - 結果表を使用したRDFグラフに対するDML操作の実行
DML操作では、すべてのスターパターン表、トリプルパターン表、チェーンパターン表が自動的にメンテナンスされます。 - 結果表を含むRDFグラフでのバルク・ロード操作の実行
- 結果表に関する統計の収集
結果表に関する最新の統計は、問合せのパフォーマンスを向上させるために重要です。
親トピック: 結果表を使用した問合せ実行の高速化
1.8.2.1 結果表への字句値の組込み
結果表のオブジェクトに字句の値を含めることもできます。
結果表には、デフォルトで、目的語値の数値識別子が含まれています。また、SPM表に字句値(RDF用語)を格納することで、RDF_VALUE$
表との結合を伴う参照が回避されて、SPARQL問合せ処理中の字句値の取得が高速化されます。
主語の字句値、または結果表に格納されているプロパティの値を含めることにした場合は、字句プロパティ値用の新しい列がスターパターン表とチェーンパターン表に追加されます。これらの列は、RDF_VALUE$
の同じ名前を持つ列に正確に対応していることに注意してください。具体的には、逆でないプロパティの字句値を結果表に含める場合、次の列が結果表に追加されます:
P<Id(property)>_VALUE_TYPE
P<Id(property)>_VNAME_PREFIX
P<Id(property)>_VNAME_SUFFIX
P<Id(property)>_LITERAL_TYPE
P<Id(property)>_LANGUAGE_TYPE
P<Id(property)>_ORDER_NUM
P<Id(property)>_ORDER_DATE
P<Id(property)>_LONG_VALUE
逆プロパティの場合、列名では先頭文字として文字'P'
ではなく'R'
が使用されます。主語の字句値(つまり、START_NODE_ID
列に格納されている数値識別子に対応している)を含めるために追加された列の名前には、P<Id(property)>
やR<Id(property)>
ではなく接頭辞'S'
を使用します。
次の例は、例1-98の変化形であり、主語の字句値と逆:fatherOf
プロパティの字句値が含まれる点が異なります。'+'
記号は、結果表に格納する必要がある字句値を示すために使用されます。ここでは、key_string
パラメータで'+S'
および'+^:fatherOf'
が使用されているため、主語と(逆):fatherOf
プロパティそれぞれのためにさらに列が追加されます。
例1-101 主語の字句値と逆プロパティの字句値の組込み
BEGIN
SEM_APIS.BUILD_RESULT_TAB(
query_pattern_type => SEM_APIS.SPM_TYPE_SVP
, result_tab_name => 'FLHF'
, rdf_graph_name => 'M1'
, key_string => ' +S :fname :lname :height +^:fatherOf '
, prefixes => ' PREFIX : <http://www.example.com#> '
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
結果表がすでに存在する場合は、SEM_APIS.ALTER_RESULT_TABサブプログラムを使用して、コマンド・パラメータの値として文字列‘ADD_S_VALUE’
または‘ADD_VALUE’
をそれぞれ使用することで、サブジェクトまたはいずれかのプロパティの字句値を含めることができます。次の例では、:lnameプロパティ
の字句値を含めます。(この例で示されていないコマンドDROP_S_VALUE
またはDROP_VALUE
を使用すると、主語の字句値列またはプロパティの字句値列をそれぞれ削除できます。)
例1-102 プロパティの字句値を追加するためのスターパターン表の変更
BEGIN
SEM_APIS.ALTER_RESULT_TAB(
query_pattern_type => SEM_APIS.SPM_TYPE_SVP
, result_tab_name => 'FLHF'
, rdf_graph_name => 'M1'
, command => 'ADD_VALUE'
, pred_name => '<http://www.example.com#lname>'
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
親トピック: 結果表の作成と管理
1.8.2.2 結果表に対するセカンダリ索引の作成および削除
結果表のセカンダリ索引を作成および削除できます。
特定のワークロードで、結果表のデフォルト索引によってすでに提供されているもの以外のアクセス・パスを介して結果表のコンテンツにアクセスする必要がある場合は、SEM_APIS.CREATE_INDEX_ON_RESULT_TABサブプログラムを使用することで、対応するセカンダリ(B+ツリー)索引を作成できます。
次の例では、例1-101で作成したスターパターン表に対するname_idx
という索引の作成を示します。key_string
パラメータ'2P 1P S'
は、そのキーが、表内の2番目のプロパティ(つまり、:lname
)に対応する列の(数値ID)値、表内の1番目のプロパティ(つまり、:fname
)からの値、主語(つまり、START_NODE_ID
列)の順に続く文字列であることを示しています。結果表内の対応する列名の形式がP<Id(property)>
であるかR<Id(property)
であるかにかかわらず、n番目のプロパティを示すには必ず<n>P
を使用することに注意してください。
プロパティの字句値が結果表に含まれている場合は、索引キーに、字句値のコンポーネントを格納する列が1つ以上含まれていることもあります。コンポーネントを示すには、<n><component-code>
という形式を使用します。ここで、n
は0 (START_NODE_ID
の場合)またはターゲット・プロパティの位置であり、component codeは、表1-25で示すとおりに、含まれている値のコンポーネント名の接尾辞に基づいて決定されます。
表1-25 字句値コンポーネント列名の接尾辞からコンポーネント・コードへのマッピング
字句値コンポーネント列名の接尾辞 | コンポーネント・コード |
---|---|
VALUE_TYPE |
VT |
VNAME_PREFIX |
VP |
VNAME_SUFFIX |
VS |
LITERAL_TYPE |
LT |
LANGUAGE_TYPE |
LA |
ORDER_NUM |
VN |
ORDER_DATE |
VD |
たとえば、キー'2P 1P 2VP 0VP S'
における2VP
および0VP
で示されているのは、そのキーに次の2つの列がそれぞれの位置で含まれているということです:
<SPM表の2番目のプロパティの列名>_VNAME_PREFIX
列S_VNAME_PREFIX
列(ここでのS
はSPM表のゼロ番目の列、つまりSTART_NODE_ID
列に対応しています)。
例1-103 結果表に対するセカンダリ(B+ツリー)索引の作成
SEM_APIS.CREATE_INDEX_ON_RESULT_TAB(
index_name. => ‘name_idx’
, query_pattern_type => SEM_APIS.SPM_TYPE_SVP
, result_tab_name => 'FLHF'
, rdf_graph_name => 'M1'
, key_string => ' 2P 1P S '
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
このサブプログラムを使用して作成された索引を削除するには、SQLのDROP INDEX <index_name>
コマンドを使用します。たとえば、次のようにします。
DROP INDEX name_idx;
親トピック: 結果表の作成と管理
1.8.2.3 結果表の削除
特定の結果表を削除できます。
次の例に示すように、SEM_APIS.DROP_RESULT_TABサブプログラムを使用して結果表を削除できます。
例1-104 結果表の削除
BEGIN
SEM_APIS.DROP_RESULT_TAB(
query_pattern_type => SEM_APIS.SPM_TYPE_SVP
, result_tab_name => 'FLHF'
, rdf_graph_name => 'M1'
, network_owner => 'RDFUSER'
, network_name => 'NET1'
);
END;
/
ただし、result_tab_name
パラメータに特殊文字列'*'を使用すると、query_pattern_type
パラメータで指定したタイプのすべての結果表を削除できます。すべての結果表を削除するには、タイプにかかわらず、query_pattern_type
パラメータにSEM_APIS.SPM_TYPE_ALL
を使用します。
親トピック: 結果表の作成と管理
1.8.2.4 インメモリー結果表
Oracle Database In-Memoryを利用すると、オプション・パラメータでINMEMORY=T
フラグを使用してインメモリー結果表を作成できます。
一般に、ディスク上の結果表は、ワークロード内の個々の問合せで一般的に発生するパターンに基づいて設計されています。結果表に問合せに不要な余分な列が含まれている場合、ディスク・スキャンのオーバーヘッドが発生する可能性があります。問合せワークロードが不明な場合や変動する場合は、すべてのプロパティを含む結果表を構築することをお薦めします。インメモリー列形式により、必要な列のみがアクセスされるようになります。すべてのプロパティを含むインメモリー結果表は1つのみ構築でき、他の結果表は許可されません。
すべてのプロパティがあるインメモリー結果表は、次の例で示すように、'INMEMORY=T'
を使用して構築できます。
例1-105 メモリー内結果表の作成
前提条件である、この例で使用される表M1_PRED_INFO
がすでに存在していることを確認してください。この表は、SEM_APIS.GATHER_SPM_INFOサブプログラムを使用して作成できます。
BEGIN
SEM_APIS.BUILD_RESULT_TAB(
rdf_graph_name =>'M1',
pred_info_tabname =>'M1_PRED_INFO',
pred_name =>NULL,
options =>' INMEMORY=T ',
degree =>2,
network_owner =>'RDFUSER',
network_name =>'NET1'
);
END;
/
ALTER TABLE “MYNET#RDF_XT$SVP_M1+__SVP1” INMEMORY;
親トピック: 結果表の作成と管理
1.8.2.5 結果表のメタデータ
RDF_SPM_INFOビューを使用して、RDFグラフで定義されている結果表についてメタデータ情報を取得できます。
表1-26 述語情報表の列
列名 | 型 | 説明 |
---|---|---|
TABLE_NAME | VARCHAR2(128) | SPM表の名前。 |
COLUMN_NAME | VARCHAR2(128) | SPM表内の列の名前(START_NODE_ID 、またはP<id(property)>またはR<id(property)> )。
|
COLUMN_ID | NUMBER | SPM表の列リスト内でのその列の位置。 |
HASVALUES | NUMBER(1) | 値の数値識別子に加えてその字句値もSPM表に格納されているかどうかを示します。 |
MODEL_ID | NUMBER | RDFグラフの数値識別子。 |
MODEL_NAME | VARCHAR2(128) | RDFグラフの名前。 |
親トピック: 結果表の作成と管理
1.8.2.6 個別プロパティについて主語ごとのカーディナリティ集計を計算するためのユーティリティ・サブプログラム
SEM_APIS.GATHER_SPM_INFOプロシージャを使用すると、トリプルの述語としての用途に基づいて、RDFグラフ内の各プロパティの主語ごとのカーディナリティ情報を格納する表を作成および移入できます。
P_VALUE_ID
列には、プロパティに対応する数値識別子が格納されます。逆プロパティの場合、P_VALUE_ID
には、そのプロパティのIDの負の値が格納されます。
このプロパティ・カーディナリティ表は、次の表で示すような構造になっています。特定のプロパティについてMAX_CNT > 1
である場合、そのプロパティは複数値です。つまり、少なくとも1つの主語リソースについて、このプロパティが、2つ以上の異なるトリプル(同じ主語と同じ述語を共有しているが異なる目的語がある)の述語として使用されています。
表1-27 述語情報表の列
列名 | タイプ | 説明 |
---|---|---|
P_VALUE_ID | NUMBER | このプロパティの値ID。負の値は、逆プロパティを示しています。 |
PRED_NAME | VARCHAR2(4000) | このプロパティの字句値。 |
MIN_CNT | NUMBER | このプロパティについての主語ごとのカーディナリティの最小値。 |
MAX_CNT | NUMBER | このプロパティについての主語ごとのカーディナリティの最大値。 |
MED_CNT | NUMBER | このプロパティについての主語ごとのカーディナリティの中央値。 |
AVG_CNT | NUMBER | このプロパティについての主語ごとのカーディナリティの平均値。 |
TOT_CNT | NUMBER | このプロパティを述語として保持するトリプルの合計数。 |
INCLUDE | VARCHAR2(30) | 使用されていません。 |
サンプルRDFデータセット(「結果表のタイプ」を参照)について、カーディナリティ情報を次の表に示します。
表1-28 述語表内のカーディナリティ情報のサンプル
P_VALUE_ID | PRED_NAME | MIN_CNT | MAX_CNT | MED_CNT | AVG_CNT | TOT_CNT | INCLUDE |
---|---|---|---|---|---|---|---|
Id(:fname) | :fname | 1 | 1 | … | … | 4 | ... |
Id(:lname) | :lname | 1 | 1 | … | … | 4 | ... |
Id(:height) | :height | 1 | 1 | … | … | 4 | ... |
Id(:email) | 1 | 2 | … | … | 4 | ... | |
Id(:fatherOf) | :fatherOf | 1 | 2 | … | … | 3 | ... |
Id(:motherOf) | :motherOf | 1 | 2 | … | … | 3 | ... |
2番目のプロシージャSEM_APIS.BUILD_RESULT_TABは、スターパターン表、トリプルパターン表、チェーンパターン表を作成および移入します。
次の例は、SEM_APIS.GATHER_SPM_INFOおよびSEM_APIS.BUILD_RESULT_TABを使用したRDFグラフの結果表のセットを示しています。これらの結果表はSPARQL問合せの実行に自動的に使用されます。この例ではSEM_MATCHを使用しますが、Apache JenaやRDFサーバーでサポートされているAPIなど、他のAPIを介して実行されるSPARQL問合せでも、結果表が自動的に使用されます。
例1-106 結果表の作成およびSPARQL問合せでのその表の使用
SQL> set echo on pages 10000 numwidth 20 lines 200 long 10000
SQL> column s format a30
SQL> column fname format a5
SQL> column lname format a5
SQL> column height format a6
SQL> column email format a25
SQL> column nick format a10
SQL> column friend format a30
SQL> column state format a5
SQL> conn rdfuser/rdfuser
Connected.
SQL> -- create an RDF network
SQL> exec sem_apis.create_rdf_network('tbs_rdf',network_owner=>'RDFUSER',network_name=>'NET1');
PL/SQL procedure successfully completed.
SQL> --move the RDF_SPM$ table and indexes defined on it to the network's tablespace
SQL> alter table NET1#RDF_SPM$ move tablespace tbs_rdf;
SQL> set serverout on;
SQL> begin
2 for idx in (select index_name from sys.user_indexes where table_name='NET1#RDF_SPM$') loop
3 execute immediate 'alter index "' || idx.index_name || '" rebuild tablespace TBS_RDF';
4 sys.dbms_output.put_line('moved (rebuild) index: ' || idx.index_name);
5 end loop;
6 end;
7 /
SQL> set serverout off;
SQL> -- create an RDF graph
SQL> exec sem_apis.create_rdf_graph('M1',null,null,network_owner=>'RDFUSER',network_name=>'NET1');
PL/SQL procedure successfully completed.
SQL> -- add some data: fname, lname, height, and nickName are single-valued; email and friendOf are multi-valued
SQL> begin
2 sem_apis.update_rdf_graph('M1',
3 'PREFIX : <http://www.example.com#>
4 PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
5 INSERT DATA {
6 :john :fname "John" ; :lname "Brown" ; :height 72
7 ; :email "john@email-example.com", "johnnyB@email-example.com"
8 ; :nickName "Johnny B"
9 ; :friendOf :ann
10 ; :address [ :addrNum 20 ; :addrStreet "Elm Street" ; :addrCityState [ :addrCity "Boston" ; :addrState "MA" ] ] .
11 :ann :fname "Ann" ; :lname "Green" ; :height 65
12 ; :email "ann@email-example.com"
13 ; :nickName "Annie"
14 ; :friendOf :john, :bill
15 ; :address [ :addrNum 10 ; :addrStreet "Main Street" ; :addrCityState [ :addrCity "New York" ; :addrState "NY" ] ] .
16 :bill :fname "Bill" ; :lname "Red" ; :height 70
17 ; :email "bill@email-example.com"
18 ; :nickName "Billy"
19 ; :friendOf :ann, :jane
20 ; :address [ :addrNum 5 ; :addrStreet "Peachtree Street" ; :addrCityState [ :addrCity "Atlanta" ; :addrState "GA" ] ] .
21 :jane :fname "Jane" ; :lname "Blue" ; :height 68
22 ; :email "jane@email-example.com", "jane2@email-example.com"
23 ; :friendOf :bill
24 ; :address [ :addrNum 101 ; :addrStreet "Maple Street" ; :addrCityState [ :addrCity "Chicago" ; :addrState "IL" ] ] .
25 }'
26 ,network_owner=>'RDFUSER'
27 ,network_name=>'NET1');
28 end;
29 /
PL/SQL procedure successfully completed.
SQL> -- create a star-pattern table for single-valued predicates :fname, :lname, :height
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_SVP
4 , result_tab_name => 'fnm_lnm_hght'
5 , rdf_graph_name => 'M1'
6 , key_string => ' :fname :lname :height '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> -- check the star-pattern table
SQL> select * from "NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT" order by start_node_id;
START_NODE_ID G8337314745347241189 P8337314745347241189 G7644445801044650266 P7644445801044650266 G4791477124431525340 P4791477124431525340
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
1399946303865654932 2838435233532231409 5036507830384741776 7949294891880010615
7024748068782994892 9071571320455459462 8802343394415720481 7603694794035016230
8531245907959123227 50859040499294923 9011354822640550059 4318017261525689661
8972322488425499169 3239737248730612593 6648986869806945928 2028730158517518732
4 rows selected.
SQL> -- create a chain-pattern table for :address/:addrCityState/:addrState
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_PCN
4 , result_tab_name => 'addr_state'
5 , rdf_graph_name => 'M1'
6 , key_string => ' S :address :addrCityState :addrState '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> -- check the chain-pattern table content
SQL> -- Note: Since generated blank node labels may differ from run to run, the 3rd and 5th column values may vary as well
SQL> select * from "NET1#RDF_XT$PCN_M1+__ADDR_STATE" order by start_node_id, 3, 5, 7;
START_NODE_ID G5055192271510902740 P5055192271510902740 G2282073771135796724 P2282073771135796724 G594560333771551504 P594560333771551504
-------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
1399946303865654932 6519232173603163724 2583525877732786353 2028557412112123936
7024748068782994892 5974521208853734660 3828178052943534859 7995579594576433205
8531245907959123227 7758805114187110754 6401534854183681859 5359878998404290171
8972322488425499169 875920943154203631 3729916732662692051 4933462079191011078
4 rows selected.
SQL> -- create triple-pattern tables for :email and :friendOf
SQL> -- :email
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_MVP
4 , result_tab_name => null
5 , rdf_graph_name => 'M1'
6 , key_string => ' :email '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> -- check the triple-pattern table
SQL> select * from "NET1#RDF_XT$MVP_M1+_P2930492586059823454" order by start_node_id;
START_NODE_ID G2930492586059823454 P2930492586059823454
-------------------- -------------------- --------------------
1399946303865654932 6100245385739701229
7024748068782994892 2096397932624357828
7024748068782994892 6480436012276020283
8531245907959123227 1846003049324830366
8531245907959123227 7834835188342349976
8972322488425499169 7251371240613573863
6 rows selected.
SQL> -- :friendOf
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_MVP
4 , result_tab_name => null
5 , rdf_graph_name => 'M1'
6 , key_string => ' :friendOf '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> -- check the triple-pattern table
SQL> select * from "NET1#RDF_XT$MVP_M1+_P1285894645615718351" order by start_node_id, 3;
START_NODE_ID G1285894645615718351 P1285894645615718351
-------------------- -------------------- --------------------
1399946303865654932 7024748068782994892
1399946303865654932 8972322488425499169
7024748068782994892 1399946303865654932
8531245907959123227 8972322488425499169
8972322488425499169 1399946303865654932
8972322488425499169 8531245907959123227
6 rows selected.
SQL> -- gather optimizer statistics on result auxiliary tables
SQL> begin
2 sem_perf.analyze_aux_tables(
3 model_name=>'M1',
4 network_owner=>'RDFUSER',
5 network_name=>'NET1');
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> -- Execute a SPARQL query that uses result tables
SQL> SELECT s, fname, lname, height, email, nick, friend, state
2 FROM TABLE(SEM_MATCH(
3 'PREFIX : <http://www.example.com#>
4 SELECT *
5 WHERE {
6 ?s :fname ?fname
7 ; :lname ?lname
8 ; :height ?height
9 ; :email ?email
10 ; :nickName ?nick
11 ; :friendOf ?friend
12 ; :address/:addrCityState/:addrState ?state
13 }'
14 ,sem_models('M1')
15 ,null,null,null,null
16 ,' '
17 ,null,null
18 ,'RDFUSER','NET1'))
19 ORDER BY 1,2,3,4,5,6,7,8;
S FNAME LNAME HEIGHT EMAIL NICK FRIEND STATE
------------------------------ ----- ----- ------ ------------------------- ---------- ------------------------------ -----
http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#bill NY
http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#john NY
http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#ann GA
http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#jane GA
http://www.example.com#john John Brown 72 john@email-example.com Johnny B http://www.example.com#ann MA
http://www.example.com#john John Brown 72 johnnyB@email-example.com Johnny B http://www.example.com#ann MA
6 rows selected.
SQL> -- See the relevant portion of the SQL translation showing the result table usage.
SQL> --
SQL> -- This SQL evaluates 9 triple patterns with only 4 joins
SQL> -- instead of the 8 joins that would normally be required
SQL> -- without result tables.
SQL> --
SQL> -- The star-pattern table is used for :fname, :lname, :height.
SQL> -- triple-pattern tables are used for :email and :friendOf.
SQL> -- RDFM_M1 (view of RDF_LINK$ for RDF graph M1) is used for :nickName.
SQL> -- The chain-pattern table is used for the sequence
SQL> -- :address/:addrCityState/:addrStat
SQL> SELECT sys.dbms_lob.substr(
2 SEM_APIS.SPARQL_TO_SQL(
3 'PREFIX : <http://www.example.com#>
4 SELECT *
5 WHERE {
6 ?s :fname ?fname
7 ; :lname ?lname
8 ; :height ?height
9 ; :email ?email
10 ; :nickName ?nick
11 ; :friendOf ?friend
12 ; :address/:addrCityState/:addrState ?state
13 }'
14 ,sem_models('M1')
15 ,null,null,null
16 ,' '
17 ,null,null
18 ,'RDFUSER','NET1'), 1004, 3377) AS SQL_TRANS_PORTION
19 FROM SYS.DUAL;
SQL_TRANS_PORTION
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT SVP0.START_NODE_ID AS S$RDFVID,
SVP0.P7644445801044650266 AS LNAME$RDFVID,
MVP1.P1285894645615718351 AS FRIEND$RDFVID,
T4.CANON_END_NODE_ID AS NICK$RDFVID,
PCN0.P594560333771551504 AS STATE$RDFVID,
SVP0.P4791477124431525340 AS HEIGHT$RDFVID,
MVP0.P2930492586059823454 AS EMAIL$RDFVID,
SVP0.P8337314745347241189 AS FNAME$RDFVID,
SVP0.START_NODE_ID AS BGP$1
FROM (
SELECT * FROM "RDFUSER".NET1#RDFM_M1) T4,
"RDFUSER"."NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT" SVP0,
"RDFUSER"."NET1#RDF_XT$PCN_M1+__ADDR_STATE" PCN0,
"RDFUSER"."NET1#RDF_XT$MVP_M1+_P2930492586059823454" MVP0,
"RDFUSER"."NET1#RDF_XT$MVP_M1+_P1285894645615718351" MVP1
WHERE SVP0.P8337314745347241189 IS NOT NULL AND
SVP0.P7644445801044650266 IS NOT NULL AND
SVP0.P4791477124431525340 IS NOT NULL AND
T4.P_VALUE_ID = 2558054308995111125 AND
1=1 AND
1=1 AND
1=1 AND
SVP0.START_NODE_ID = MVP0.START_NODE_ID AND
SVP0.START_NODE_ID = T4.START_NODE_ID AND
SVP0.START_NODE_ID = MVP1.START_NODE_ID AND
SVP0.START_NODE_ID = PCN0.START_NODE_ID AND
1=1
1 row selected.
例1-107 結果表への字句値の組込み
次の例では、結果表に字句値を含めます。この例は例1-106の後に続くものであることに留意してください。SQL> conn rdfuser/rdfuser
SQL> -- Drop and recreate the FNM_LNM_HGHT SVP table, with in-line lexical values for the :fname and :height properties.
SQL> -- Check metadata for the new result table to verify that HASVALUES=1 for the two properties whose lexical values are in-lined.
SQL> exec sem_apis.drop_result_tab(sem_apis.SPM_TYPE_SVP, ' fnm_lnm_hght ', 'm1', network_owner=>'rdfuser', network_name=>'net1');
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_SVP
4 , result_tab_name => 'fnm_lnm_hght'
5 , rdf_graph_name => 'M1'
6 , key_string => ' S +:fname :lname +:height '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL>
SQL> select * from net1#rdf_spm_info where table_name like '%SVP%FNM_LNM_HGHT' order by table_name, column_id;
TABLE_NAME COLUMN_NAME COLUMN_ID HASVALUES MODEL_ID MODEL_NAME
---------------------------------------- -------------------- -------------------- -------------------- -------- ----------
NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT START_NODE_ID 1 0 1 M1
NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT P8337314745347241189 3 1 1 M1
NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT P7644445801044650266 5 0 1 M1
NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT P4791477124431525340 7 1 1 M1
4 rows selected.
SQL>
SQL> -- Drop and recreate the ADDR_STATE chain-pattern table, with in-line lexical values for the :addrState property.
SQL> -- Check metadata for the new table to verify that HASVALUES=1 for the :addrState property.
SQL> exec sem_apis.drop_result_tab(sem_apis.SPM_TYPE_PCN, ' addr_state ', 'm1', network_owner=>'rdfuser', network_name=>'net1');
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_PCN
4 , result_tab_name => 'addr_state'
5 , rdf_graph_name => 'M1'
6 , key_string => ' S :address :addrCityState +:addrState '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL>
SQL> select * from net1#rdf_spm_info where table_name like '%PCN%ADDR_STATE' order by table_name, column_id;
TABLE_NAME COLUMN_NAME COLUMN_ID HASVALUES MODEL_ID MODEL_NAME
---------------------------------------- -------------------- -------------------- -------------------- -------- ----------
NET1#RDF_XT$PCN_M1+__ADDR_STATE START_NODE_ID 1 0 1 M1
NET1#RDF_XT$PCN_M1+__ADDR_STATE P5055192271510902740 3 0 1 M1
NET1#RDF_XT$PCN_M1+__ADDR_STATE P2282073771135796724 5 0 1 M1
NET1#RDF_XT$PCN_M1+__ADDR_STATE P594560333771551504 7 1 1 M1
4 rows selected.
SQL>
SQL> -- Drop and recreate the triple-pattern table for the :email property (id: 2930492586059823454), with in-line lexical values for the :email property.
SQL> -- Check metadata for the new table to verify that HASVALUES=1 for the :email property.
SQL> exec sem_apis.drop_result_tab(sem_apis.SPM_TYPE_MVP, '<http://www.example.com#email>', 'm1', network_owner=>'rdfuser', network_name=>'net1');
PL/SQL procedure successfully completed.
SQL> BEGIN
2 SEM_APIS.BUILD_RESULT_TAB(
3 query_pattern_type => SEM_APIS.SPM_TYPE_MVP
4 , result_tab_name => null
5 , rdf_graph_name => 'M1'
6 , key_string => ' +:email '
7 , prefixes => ' PREFIX : <http://www.example.com#> '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL>
SQL> select * from net1#rdf_spm_info where table_name like '%MVP%P2930492586059823454' order by table_name, column_id;
TABLE_NAME COLUMN_NAME COLUMN_ID HASVALUES MODEL_ID MODEL_NAME
---------------------------------------- -------------------- -------------------- -------------------- -------- ----------
NET1#RDF_XT$MVP_M1+_P2930492586059823454 START_NODE_ID 1 0 1 M1
NET1#RDF_XT$MVP_M1+_P2930492586059823454 P2930492586059823454 3 1 1 M1
2 rows selected.
SQL>
SQL> -- gather optimizer statistics on result auxiliary tables
SQL> begin
2 sem_perf.analyze_aux_tables(
3 model_name=>'M1',
4 network_owner=>'RDFUSER',
5 network_name=>'NET1');
6 end;
7 /
PL/SQL procedure successfully completed.
SQL>
SQL> -- Execute a SPARQL query that uses result tables
SQL> SELECT s, fname, lname, height, email, nick, friend, state
2 FROM TABLE(SEM_MATCH(
3 'PREFIX : <http://www.example.com#>
4 SELECT *
5 WHERE {
6 ?s :fname ?fname
7 ; :lname ?lname
8 ; :height ?height
9 ; :email ?email
10 ; :nickName ?nick
11 ; :friendOf ?friend
12 ; :address/:addrCityState/:addrState ?state
13 }'
14 ,sem_models('M1')
15 ,null,null,null,null
16 ,' '
17 ,null,null
18 ,'RDFUSER','NET1'))
19 ORDER BY 1,2,3,4,5,6,7,8;
S FNAME LNAME HEIGHT EMAIL NICK FRIEND STATE
------------------------------ ----- ----- ------ ------------------------- ---------- ------------------------------ -----
http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#bill NY
http://www.example.com#ann Ann Green 65 ann@email-example.com Annie http://www.example.com#john NY
http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#ann GA
http://www.example.com#bill Bill Red 70 bill@email-example.com Billy http://www.example.com#jane GA
http://www.example.com#john John Brown 72 john@email-example.com Johnny B http://www.example.com#ann MA
http://www.example.com#john John Brown 72 johnnyB@email-example.com Johnny B http://www.example.com#ann MA
6 rows selected.
SQL>
SQL> -- See the relevant portion of the SQL translation showing SPM table usage including in-line lexical values.
SQL> --
SQL> -- The number of joins with the RDF_VALUE$ table (for looking up lexical values) goes down from 8 to 4
SQL> -- because out of the 8 variables being projected, 4 -- fname, height, email, state -- appear
SQL> -- with properties whose lexical values are present in-line in the available result tables.
SQL> --
SQL> SELECT SEM_APIS.SPARQL_TO_SQL(
2 'PREFIX : <http://www.example.com#>
3 SELECT *
4 WHERE {
5 ?s :fname ?fname
6 ; :lname ?lname
7 ; :height ?height
8 ; :email ?email
9 ; :nickName ?nick
10 ; :friendOf ?friend
11 ; :address/:addrCityState/:addrState ?state
12 }'
13 ,sem_models('M1')
14 ,null,null,null
15 ,' '
16 ,null,null
17 ,'RDFUSER','NET1')
18 FROM SYS.DUAL;
SEM_APIS.SPARQL_TO_SQL('PREFIX:<HTTP://WWW.EXAMPLE.COM#>SELECT*WHERE{?S:FNAME?FN
--------------------------------------------------------------------------------
SELECT * FROM (
SELECT … <omitted> …
FROM (SELECT … <omitted> …
FROM (
SELECT * FROM "RDFUSER".NET1#RDFM_M1) T4,
"RDFUSER"."NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT" SVP0,
"RDFUSER"."NET1#RDF_XT$PCN_M1+__ADDR_STATE" PCN0,
"RDFUSER"."NET1#RDF_XT$MVP_M1+_P2930492586059823454" MVP0,
"RDFUSER"."NET1#RDF_XT$MVP_M1+_P1285894645615718351" MVP1
WHERE 1=1 AND
1=1 AND
1=1 AND
1=1 AND
SVP0.P8337314745347241189 IS NOT NULL AND
SVP0.P7644445801044650266 IS NOT NULL AND
SVP0.P4791477124431525340 IS NOT NULL AND
T4.P_VALUE_ID = 2558054308995111125 AND
1=1 AND
1=1 AND
1=1 AND
SVP0.START_NODE_ID = MVP0.START_NODE_ID AND
SVP0.START_NODE_ID = T4.START_NODE_ID AND
SVP0.START_NODE_ID = MVP1.START_NODE_ID AND
SVP0.START_NODE_ID = PCN0.START_NODE_ID AND
1=1) R, "RDFUSER".NET1#RDF_VALUE$ V0, "RDFUSER".NET1#RDF_VALUE$ V1, "RDFUSER".NET1#RDF_VALUE$ V2, "RDFUSER".NET1#RDF_VALUE$ V3
WHERE (1=1) AND (R.S$RDFVID = V0.VALUE_ID) AND (R.LNAME$RDFVID = V1.VALUE_ID) AND (R.FRIEND$RDFVID = V2.VALUE_ID) AND (R.NICK$RDFVID = V3.VALUE_ID)
) WHERE (1=1)
1 row selected.
SQL>
SQL> -- In addition to value projection. In-line lexical values
SQL> -- can be used to evaluate FILTER conditions.
SQL> -- The value for ?height can be taken directly from the
SQL> -- SVP table in this case.
SQL> SELECT s, height
2 FROM TABLE(SEM_MATCH(
3 'PREFIX : <http://www.example.com#>
4 SELECT ?s ?height
5 WHERE {
6 ?s :fname ?fname
7 ; :lname ?lname
8 ; :height ?height
9 FILTER (?height >= 72)
10 }'
11 ,sem_models('M1')
12 ,null,null,null,null
13 ,' '
14 ,null,null
15 ,'RDFUSER','NET1'))
16 ORDER BY 1,2;
S HEIGHT
------------------------------ ------
http://www.example.com#john 72
1 row selected.
SQL>
SQL> -- The SQL translation shows in-line lexical value usage for ?height >= 72.
SQL> SELECT SEM_APIS.SPARQL_TO_SQL(
2 'PREFIX : <http://www.example.com#>
3 SELECT ?s ?height
4 WHERE {
5 ?s :fname ?fname
6 ; :lname ?lname
7 ; :height ?height
8 FILTER (?height >= 72)
9 }'
10 ,sem_models('M1')
11 ,null,null,null
12 ,' '
13 ,null,null
14 ,'RDFUSER','NET1') AS SQL_TRANS
15 FROM SYS.DUAL;
SQL_TRANS
--------------------------------------------------------------------------------
SELECT * FROM (
SELECT … <omitted> …
FROM (SELECT …<omitted> …
FROM "RDFUSER"."NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT" SVP0
WHERE 1=1 AND
SVP0.P8337314745347241189 IS NOT NULL AND
SVP0.P7644445801044650266 IS NOT NULL AND
SVP0.P4791477124431525340 IS NOT NULL AND
1=1 AND
1=1 AND
(SVP0.P4791477124431525340_ORDER_NUM >= to_number(72))) R, "RDFUSER".NET1#RDF_VALUE$ V0
WHERE (1=1) AND (R.S$RDFVID = V0.VALUE_ID)
) WHERE (1=1)
1 row selected.
SQL>
例1-108 結果補助表でのセカンダリ索引の作成
次の例では、結果の補助表に対するセカンダリ索引の作成を示します。この例は例1-106と例1-107の後に続くものであることに留意してください。
SQL>
SQL> conn rdfuser/rdfuser
Connected.
SQL>
SQL> -- create index on the ORDER_NUM (VN) component of the lexical value of the :height property.
SQL> -- This component is stored as a column in the FNM_LNM_HGHT SVP table.
SQL> -- It holds the numeric value for RDF literals of numeric type.
SQL> -- Since the :height property is the 3rd property in the SVP table, it is referred to using 3VN in the key_string argument below.
SQL> BEGIN
2 SEM_APIS.CREATE_INDEX_ON_RESULT_TAB(
3 index_name => 'height_idx'
4 , query_pattern_type => SEM_APIS.SPM_TYPE_SVP
5 , result_tab_name => 'fnm_lnm_hght'
6 , rdf_graph_name => 'M1'
7 , key_string => ' 3VN S '
8 , degree => 2
9 , network_owner => 'RDFUSER'
10 , network_name => 'NET1'
11 );
12 END;
13 /
PL/SQL procedure successfully completed.
SQL>
SQL> -- EXPLAIN PLAN for the SPARQL query above involving "height >= 72" shows use of this index for access.
SQL> EXPLAIN PLAN FOR
2 SELECT s, height
3 FROM TABLE(SEM_MATCH(
4 'PREFIX : <http://www.example.com#>
5 SELECT ?s ?height
6 WHERE {
7 ?s :fname ?fname
8 ; :lname ?lname
9 ; :height ?height
10 FILTER (?height >= 72)
11 }'
12 ,sem_models('M1')
13 ,null,null,null,null
14 ,' '
15 ,null,null
16 ,'RDFUSER','NET1'))
17 ORDER BY 1,2;
Explained.
SQL>
SQL> select plan_table_output from table(dbms_xplan.display('plan_table',null,'basic +predicate'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3046664063
-------------------------------------------------------------------------------------
| Id | Operation | Name |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT ORDER BY | |
| 2 | NESTED LOOPS | |
| 3 | NESTED LOOPS | |
| 4 | VIEW | |
|* 5 | TABLE ACCESS BY INDEX ROWID BATCHED| NET1#RDF_XT$SVP_M1+__FNM_LNM_HGHT |
|* 6 | INDEX RANGE SCAN | HEIGHT_IDX |
|* 7 | INDEX UNIQUE SCAN | NET1#C_PK_VID |
| 8 | TABLE ACCESS BY INDEX ROWID | NET1#RDF_VALUE$ |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("SVP0"."P8337314745347241189" IS NOT NULL AND
"SVP0"."P7644445801044650266" IS NOT NULL AND "SVP0"."P4791477124431525340"
IS NOT NULL)
6 - access("SVP0"."P4791477124431525340_ORDER_NUM">=72 AND
"SVP0"."START_NODE_ID">0 AND "SVP0"."P4791477124431525340_ORDER_NUM" IS NOT
NULL)
filter("SVP0"."START_NODE_ID">0)
7 - access("R"."S$RDFVID"="V0"."VALUE_ID")
27 rows selected.
SQL>
SQL> select column_name, column_position from all_ind_columns where index_name='HEIGHT_IDX' order by 2;
COLUMN_NAME COLUMN_POSITION
------------------------------ --------------------
P4791477124431525340_ORDER_NUM 1
START_NODE_ID 2
親トピック: 結果表の作成と管理
1.8.2.7 結果表を含むRDFグラフに対するDML操作の実行
DML操作では、すべてのスターパターン表、トリプルパターン表、チェーンパターン表が自動的にメンテナンスされます。
- 削除: 削除操作の場合、トリプル・パターン表から対応する行が削除されます。スターパターン表では、対応する列値は、値列を含めてNULLに設定されます。チェーンパターン表では、削除されたトリプルを使用する行は、チェーン内のリンクの削除を反映するために削除されます。
- 挿入: 挿入操作では、新しいサブジェクト行または対応する列値がトリプルパターン表に挿入されます(値列を含む値が存在しない場合)。スターパターン表およびチェーンパターン表では、既存の値がNULLの場合、新しいサブジェクト行または列値が挿入されます。既存の値とは異なる値が挿入されると、スターパターン表の制約違反に対してエラーが発生します。
親トピック: 結果表の作成と管理
1.8.2.8 結果表を含むRDFグラフでのバルク・ロード操作の実行
RDFデータをRDFグラフにバルク・ロードするときに、そのグラフに結果表が存在する場合、それらはデータのロード前に切り捨てられ、ロード完了後に再移入されます。
親トピック: 結果表の作成と管理
1.8.2.9 結果表の統計の収集
結果表の統計を最新にすることは、優れた問合せパフォーマンスを得るために重要です。
SEM_PERF.ANALYZE_AUX_TABLESプロシージャをコールして、結果表の統計を収集できます。
親トピック: 結果表の作成と管理
1.8.3 結果表のSPARQL問合せオプション
結果表が存在する場合、SPARQL問合せは結果表を自動的に使用します。
結果表を利用するために既存のSPARQLワークロードを変更する必要はありません。ただし、結果表の使用を微調整するために、いくつかの新しい問合せオプションおよびオプティマイザ・ヒントを使用できます。
次の問合せオプションは、SEM_MATCH
のoptions引数、またはApache JenaやRDFサーバーのサポートによって使用されるSEM_FS_NS
接頭辞で使用できます。
COST_BASED_SPM_OPT
- 結果表の使用方法は、問合せ実行計画のコストによって決定されますDISABLE_SPM_OPT
- 結果表(スターパターン、トリプルパターン、チェーンパターン)を使用しないDISABLE_SVP_OPT
– スターパターン表を使用しないDISABLE_PCN_OPT
– チェーンパターン表を使用しないDISABLE_MVP_OPT
– トリプルパターン表を使用しないDISABLE_SPM_VALUES_OPT
- 値の投影またはフィルタの評価(スターパターン、トリプルパターン、チェーンパターン)に結果表でインライン字句値を使用しないDISABLE_SPM_VALUE_PROJ_OPT
- 値の投影(スターパターン、トリプルパターン、チェーンパターン)に結果表でインライン字句値を使用しないMIN_SVP_CLUSTER_SIZE(n)
- スターパターン表に含まれるn個以上のプロパティを参照するスター・パターン・クラスタにのみスターパターン表を使用します(デフォルトではn = 1)。PREFER_PCN=T
- スターパターン表またはチェーンパターン表を使用してトリプルパターンを評価できる場合、チェーンパターン表を選択します(デフォルトの動作はスターパターン表を使用します)。
HINT0
ヒント文字列、SEM_MATCH
のoptions引数、およびApache JenaやRDFサーバーのサポートによって使用されるSEM_FS_NS
接頭辞では、次の問合せオプティマイザ・ヒントを使用できます。
ALL_SPM_HASH / ALL_SPM_NL
– 結果表を持つすべての結合(スターパターン、トリプルパターン、チェーンパターン)にハッシュ/ネステッド・ループ結合を使用します。ALL_SVP_HASH / ALL_SVP_NL
- スターパターン表とのすべての結合にハッシュ/ネステッド・ループ結合を使用しますALL_MVP_HASH / ALL_MVP_NL
- トリプルパターン表とのすべての結合にハッシュ/ネステッド・ループ結合を使用しますALL_PCN_HASH / ALL_PCN_NL
- チェーンパターン表とのすべての結合にハッシュ/ネステッド・ループ結合を使用します
親トピック: 結果表を使用した問合せ実行の高速化
1.8.4 結果表を使用する場合の特別な考慮事項
この項では、結果表の使用時に考慮する必要があるいくつかの制限事項を説明します。
- 結果表は、単一のRDFグラフでのみサポートされます。RDFグラフ収集および推論グラフはサポートされていません。
- 結果表は、Oracle Label Securityを使用しているRDFネットワークではサポートされていません。
- フラッシュバック問合せは、結果表ではサポートされていません。
- 結果表を含むRDFグラフは、SEM_APIS.MERGE_RDF_GRAPHS操作で宛先RDFグラフとして使用できません。
- GeoSPARQL関数またはOracle Text関数を使用するSPARQL問合せは、結果表を使用しません。
- +および*プロパティ・パス式の評価では結果表は使用されません。
- 結果表は、
SEM_APIS.APPEND_SEM_NETWORK_DATA
、SEM_APIS.MOVE_SEM_NETWORK_DATA
またはSEM_APIS.RESTORE_SEM_NETWORK_DATA
操作ではサポートされていません。
親トピック: 結果表を使用した問合せ実行の高速化